Archive for the 'Azure' Category

15
Feb
13

Azure websocket server with node.js and socket.io

Peter Daukintis

If you haven’t previously done this download your Azure publish settings file from here https://windows.azure.com/download/publishprofile.aspx

This will contain your management certificate and details for each of your Azure subscriptions.

 

If you have multiple Azure subscriptions ensure that you have set the ‘current’ one to be the one you wish to use:

Select-AzureSubscription –SubscriptionName your_subscription_name

You can confirm this is set by using,

Get-AzureSubscription -Current 

Then, to create the Azure project

New-AzureServiceProject your_project_name

This will create the files needed by the Azure cloud project (including deployment settings, cloud/local configuration files and a service definition file).

Add-AzureNodeWorkerRole

This will add a WorkerRole folder which contains the Node project

ps2

then, from within the WorkRole folder,

npm install azure (optional – enables access to azure services within your node project see https://npmjs.org/package/azure)

npm install socket.io

navigate to the worker role folder and replace the code in server.js with the following:

   1:  var http = require('http'); 
   2:  var io = require('socket.io'); 
   3:  var port = process.env.port || 1337; 
   4:  var server = http.createServer(function (req, res) { 
   5:      res.writeHead(200, { 'Content-Type': 'text/plain' }); 
   6:      res.end('Hello World 2\n'); 
   7:  }).listen(port);
   8:   
   9:  var socket = io.listen(server); 
  10:  socket.on('connection', function (client) { 
  11:      socket.emit('news', { hello: 'world' }); 
  12:      client.on('message', function(){ 
  13:          console.log('message arrive'); 
  14:          client.send('some message'); 
  15:      });
  16:   
  17:      client.on('disconnect', function(){ 
  18:          console.log('connection closed'); 
  19:      }); 
  20:  });
  21:   

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }


then

Publish-AzureServiceProject

Note that subsequent publish commands will result in an upgrade…

publish

 

Create a .NET client to test the server

Create a new c# console app in visual studio, add SocketIO .NET client Nuget package (Install-Package SocketIO4Net.Client)

SocketIONetClientNuget

Paste the following into the console app…

   1:          static void Main(string[] args)
   2:          {
   3:              Console.WriteLine("Starting TestSocketIOClient Example...");
   4:   
   5:              using (var socket = new Client("http://your_project_name.cloudapp.net/"))
   6:              {
   7:                  socket.Opened += SocketOpened;
   8:                  socket.Message += SocketMessage;
   9:                  socket.SocketConnectionClosed += SocketConnectionClosed;
  10:                  socket.Error += SocketError;
  11:   
  12:                  socket.Connect();
  13:   
  14:                  Console.ReadLine();
  15:              }
  16:          }
  17:   
  18:          private static void SocketConnectionClosed(object sender, EventArgs e)
  19:          {
  20:              Console.WriteLine("CLOSED");
  21:          }
  22:   
  23:          private static void SocketError(object sender, ErrorEventArgs e)
  24:          {
  25:              Console.WriteLine(e.Message);
  26:          }
  27:   
  28:          private static void SocketMessage(object sender, MessageEventArgs e)
  29:          {
  30:              Console.WriteLine(e.Message.MessageType.ToString());
  31:          }
  32:   
  33:          private static void SocketOpened(object sender, EventArgs e)
  34:          {
  35:              Console.WriteLine("OPENED");
  36:          }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

That’s it.

24
Feb
10

Azure + Silverlight 4 + RIA Services + MVC2 (Part 5)

by Peter Daukintis

To illustrate how the final architecture hangs together I will take the AudioModule PRISM module from the previous post and link it up with a RIA services class library running on the server. So, the first step is to add a RIA Services class library to the solution:

RIAServicesClassLibrary

This step will create two new sub-projects – one for the client – and one for the server. I won’t be using the client library so will delete it and use the AudioModule in its place. So I have removed the project without the .Web suffix. Also, I will delete the default Class.cs that comes with the server-side library project. Then the next step is to add a Domain Service Class to the project using the right-click Add New Item menu. I called this AudioDomainContext to match up with the client-side PRISM module.

    [EnableClientAccess()]
    public class AudioDomainService : DomainService
    {
    }

This is the empty class that the wizard creates for you – since I don’t want to use any of the pre-built domain context’s such as the ones provided for Linq2Sql or Entity framework. Ultimately, I want to use Azure Table storage for this walkthrough but it’s nice to know that I have the flexibility to mix and match these. For this part in the series I am going to make a dummy data layer but for my overall architecture just imagine that I could use the TestEntityRepository behind the ITestEntityRepository from the second post in this series. So, here’s the code for the AudioDomainService:

    [EnableClientAccess()]
    public class AudioDomainService : DomainService
    {
        public IQueryable<AudioEntity> GetAudio()
        {
            var audioEntities = new List<AudioEntity> {new AudioEntity { Id = 1, Title = "Title1", Artist = "Artist1"}};
            return audioEntities.AsQueryable();
        }
    }

    [MetadataType(typeof(AudioEntityMetadata))]
    public class AudioEntity
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Artist { get; set; }
    }

    public class AudioEntityMetadata
    {
        [Key]
        public int Id { get; set; }
        public string Title { get; set; }
        public string Artist { get; set; }
    }

First notice I have just new’ed up a list of AudioEntity instances to act as my dummy data layer in this case (for the purpose of this demonstration it doesn’t really matter). The EnableClientAccess attribute on the class marks it as a class to use to generate the client-side code from. The RA Services code generation layer knows from inspecting the methods here that return IQueryable what are the entities and methods to transfer over to the client. You can add any methods you like in here and those returning IQueryable will later magically appear on your client.

Also the entity has a ‘buddy class’ used to define it’s metadata. This is achieved by marking up the properties with attributes. The buddy class is only necessary if the entity is actually generated externally by, for example, Linq2Sql. This method is used as you can’t mark up the generated code as you will lose your attributes each time you regenerate. So, in my case I could have just marked the AudioEntity class with attributes but I have used this to illustrate the difference.

So, this leaves one more step to link client and server.

In the Project settings for the AudioModule PRISM module:

rialink

At the bottom, there is a dropdown box called .NET RIA Services link and strangely this will have no options in it. In order to edit the link it is currently necessary to edit the project file by hand and find the following tag and type in it’s value:

    <LinkedServerProject>..RIAAudioService.WebRIAAudioService.Web.csproj</LinkedServerProject>

Now, the next time you open the project properties it will be set up correctly to point to the server-side RIA services class library project. Now, when you build the solution the client-side code part of RIA services will get generated.

RIAClientSide

In order to see the code you need to select ‘Show All Files’ at the top of the Solution Explorer and you will see a Generated_Code folder and the generated code will be in there with a suffux .Web.g.cs.

When you try to build this you will find some missing references – here’s the list of references you will need to add:

  • System.Windows.Ria
  • System.Runtime.Serialization
  • System.ServiceModel
  • System.ComponentModel.DataAnnotations

Now of course, you are enabled to use the client-side parts of RIA services.

Client-side

 

The first thing I can do is write some code like the following:

using System;
using System.Windows.Ria;
using RIAAudioService.Web;

namespace AudioModule
{
    public class AudioViewModel
    {
        public AudioViewModel()
        {
            var audioDomainContext = new AudioDomainContext();
            EntityQuery<AudioEntity> entityQuery = audioDomainContext.GetAudioQuery();

            audioDomainContext.Load(entityQuery, new Action<LoadOperation<AudioEntity>>(LoadComplete), null);
        }

        private void LoadComplete(LoadOperation<AudioEntity> obj)
        {
            
        }
    }
}

 

If you are not familiar with MVVM I would recommend you watch this video http://blog.lab49.com/archives/2650 by Jason Dolinger which is a very good introduction to the subject. In brief, the class is a ViewModel which provides properties which the xaml view will bind directly to. So, notice that we can use our entity that was defined on the server and we can asynchronously load our data.

There are a few other aspects to cover here; tooling support in VS2010 and server-defined validation – I will give a quick lowdown here but won’t go into too much detail.

The server-defined validation uses Data Annotations and you simply mark up the entity classes on the server and this metadata flows across to the client and can be used in client-side validation. See http://babaandthepigman.spaces.live.com/blog/cns!4F1B7368284539E5!167.entry?&_c02_vws=1&wa=wsignin1.0&sa=613584902 or http://msdn.microsoft.com/en-us/magazine/dd695920.aspx for further details about Data Annotations.

In visual studio 2010 go to Data > Show Data Sources from the main menu. This will open up a panel with your data sources in like the following:

RIADataSources 

These items can be manipulated and dragged out onto the designer surface to automatically create user interface elements. This doesn’t really fit with the architecture I have been trying to create as I want everything to be separate and this move will somewhat shackle the view to the data layer. However, may be useful in smaller apps and for rapid development scenarios. See here for a good video introducing vs2010 tooling support http://www.silverlight.net/learn/videos/silverlight-4-beta-videos/ria-services-support-visual-studio-2010/.

And that’s the end; I hope you enjoyed these posts! I’m pleasantly satisfied with the end result and did not expect it to be so straightforward and flexible.

Technorati Tags: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Windows Live Tags: Azure,AudioModule,PRISM,module,library,server,Class,Domain,Service,menu,AudioDomainContext,AudioDomainService,DomainService,context,framework,storage,series,data,TestEntityRepository,ITestEntityRepository,code,IQueryable,List,Title,Artist,AsQueryable,MetadataType,AudioEntityMetadata,purpose,demonstration,marks,generation,buddy,example,method,difference,Project,bottom,LinkedServerProject,RIAAudioService,Files,Explorer,Generated_Code,folder,System,Runtime,Serialization,ServiceModel,ComponentModel,DataAnnotations,AudioViewModel,EntityQuery,GetAudioQuery,Load,Action,LoadOperation,LoadComplete,MVVM,Jason,Dolinger,introduction,subject,ViewModel,validation,Annotations,classes,spaces,magazine,studio,panel,items,user,interface,development,result,instances,methods,options,references,aspects,metadata,blog

21
Feb
10

Azure + Silverlight 4 + RIA Services + MVC2 (Part 4)

by Peter Daukintis

So, now I know how to set up a basic project, store and retrieve my data in Azure Table storage and have incorporated the asp.net providers that use Table Storage it’s time to turn my attention towards finding the right architecture to make the most out of RIA Services. I would like to use the PRISM libraries with an MVVM approach but I’m not sure how well these play with RIA Services in a Silverlight Business Application.

The first step was to get a version of PRISM that works with vs2010 – this I found here http://blogs.southworks.net/dschenkelman/2009/11/09/prism-2-composite-application-guidance-for-wpf-silverlight-migrated-to-visual-studio-2010-beta-2/

Then I imagined that the solution would consist of using PRISM’s module support to load each tab of the Silverlight Business Application on demand. This should support only downloading xap’s that the user has elected to view. I wasn’t searching for a fully dynamic solution – just a middle ground where the application is split up into separate modules – and the right environment in which to improve the design later.

The solution I went for was to create hyperlinks and related xaml files which fit with the Silverlight 4 navigation scenario but to define a PRISM ‘region’ inside each navigation page. If you are not familiar with PRISM regions or in general I would suggest that you take a look at Mike Taulty’s series here http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/10/27/prism-and-silverlight-screencasts-on-channel-9.aspx. The regions will act as a placeholder for the user interface which will later be supplied by the modules. So, effectively each tab is hard-coded and it’s view defines a region to be filled in later.

Here’s an example of one of the xaml pages:

<navigation:Page x:Class="PrismNav.Views.AudioModule"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           mc:Ignorable="d"
           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           xmlns:Regions="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation" 
           d:DesignWidth="640" d:DesignHeight="480"
           Title="Audio Module">
  <Grid x:Name="LayoutRoot">
    <ItemsControl x:Name="Module2Region" Regions:RegionManager.RegionName="Module2Region"/>
  </Grid>
</navigation:Page>

and here’s an example of the link in the main xaml file:

                        <Rectangle x:Name="Divider3" Style="{StaticResource DividerStyle}"/>

                        <HyperlinkButton x:Name="AudioModuleLink" Style="{StaticResource LinkStyle}" 
                                     NavigateUri="/AudioModule" TargetName="ContentFrame" Content="Audio Module"/>

One of these are added for each required tab.

Some extra steps are required to initialise the PRISM environment:

Bootstrapper – add a bootstrapper class to the project to let PRISM know about the main window and also to intialise a module catalog.

    public class BootStrapper : UnityBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            Shell shell = Container.Resolve<Shell>(); 
            Application.Current.RootVisual = shell; 
            return shell;
        }

        protected override IModuleCatalog GetModuleCatalog()
        {
            ModuleCatalog moduleCatalog = ModuleCatalog.CreateFromXaml(new Uri("PrismNav;component/ModuleCatalog.xaml", 
             UriKind.Relative));
            return moduleCatalog;
        }
    }
}

Where the Shell is the main page of the Silverlight app renamed to Shell.xaml (to adhere to convention). It is also necessary to kick off a call to run the bootstrapper code – this can be done like this

            var bootStrapper = new BootStrapper();
            bootStrapper.Run();
            _unityContainer = bootStrapper.Container;

inserted into the Application_Startup method in App.xaml.cs (Note that I take a reference to the bootstrapper’s unity container here – this I use to resolve creation of the Shell view class in InitializeRootVisual() as in the generated code it uses new Shell() with no ctor parameters but I have modified my Shell class to be constructor injected with the IModuleManager interface).

The module catalog you can add to the app and it’s contents are like this:

m:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                 xmlns:m="clr-namespace:Microsoft.Practices.Composite.Modularity;assembly=Microsoft.Practices.Composite">
    <m:ModuleInfoGroup Ref="HomeModule.xap" InitializationMode="OnDemand">
        <m:ModuleInfo ModuleName="HomeModule.InitModule"
                      ModuleType="HomeModule.InitModule, HomeModule, Version=1.0.0.0"/>
    </m:ModuleInfoGroup>
    <m:ModuleInfoGroup Ref="AudioModule.xap" InitializationMode="OnDemand">
        <m:ModuleInfo ModuleName="AudioModule.InitModule"
                      ModuleType="AudioModule.InitModule, AudioModule, Version=1.0.0.0"/>
    </m:ModuleInfoGroup>
</m:ModuleCatalog>

This describes where the code for the modules are and some extra settings describing how the module should be loaded, etc..Now, onto creating a module:

using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.Regions;

namespace AudioModule
{
    public class InitModule : IModule
    {
        private readonly IRegionManager _regionManager;

        public InitModule(IRegionManager regionManager)
        {
            _regionManager = regionManager;
        }

        #region IModule Members

        public void Initialize()
        {
            _regionManager.RegisterViewWithRegion("Module2Region", typeof(Audio));
        }

        #endregion
    }
}

Add a new Silverlight application to the solution and empty out it’s contents and add in the code above which provides the PRISM module definition. Add a xaml file which will be the ui you wish to be injected into the region and the Initialise call above registers this modules interest in the ‘module2Region’.

So, now we have two ends of the story – these need to be connected together and here’s how to do it.

When the tabbed hyperlinks are clicked on a Silverlight Business Application there is some code in the code behind for the main shell file which is triggered – see the ContentFrame_Navigated method. This is just used to set the states of the hyperlink controls but is a handy place to load the modules. This can be done as below:

        private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
        {
            string blah = e.Uri.ToString();
            if (blah.EndsWith("Module"))
            {
                blah = blah.Remove(0, 1);
                _moduleManager.LoadModule(blah + ".InitModule");
            }

            foreach (UIElement child in LinksStackPanel.Children)
            {
                HyperlinkButton hb = child as HyperlinkButton;
                if (hb != null && hb.NavigateUri != null)
                {
                    if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
                    {
                        VisualStateManager.GoToState(hb, "ActiveLink", true);
                    }
                    else
                    {
                        VisualStateManager.GoToState(hb, "InactiveLink", true);
                    }
                }
            }
        }

Please note that I have just used a ‘quick and dirty’ naming convention to get the module name from the Uri – this obviously doesn’t scale too well – but will do for now!

And that’s it – although it’s not perfect it is the start of a modular architecture. In my next post I will investigate how to have the RIA Services code play nicely with this modular architecture and allow it to generate my client side service calls + entities. 

21
Feb
10

Azure + Silverlight 4 + RIA Services + MVC2 (Part 3)

by Peter Daukintis

Next up is getting the authentication service to use azure table storage.

To do this you need to get the additional azure code samples from here http://code.msdn.microsoft.com/windowsazuresamples and include the asp providers project into the solution (this will need to be up converted as the project is for vs2008). Then include a reference to this in the host website project.

For my scenario, where I am not running my app as a cloud service, I need to add settings to my web.config file to provide settings for the various providers. It was quite challenging to work out what exactly was required here but I got things working with the following in my web.config:

    <membership defaultProvider="TableStorageMembershipProvider" userIsOnlineTimeWindow = "20">
      <providers>
        <clear/>

        <add name="TableStorageMembershipProvider"
             type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageMembershipProvider"
             description="Membership provider using table storage"
             enablePasswordRetrieval="false"
             enablePasswordReset="true"
             requiresQuestionAndAnswer="false"
             minRequiredPasswordLength="1"
             minRequiredNonalphanumericCharacters="0"
             requiresUniqueEmail="true"
             passwordFormat="Clear"
             applicationName="YourAppName"
             accountName="youracctname"
             sharedKey="xxxxxx"
             allowInsecureRemoteEndpoints="true"
             tableServiceBaseUri="http://youracctname.table.core.windows.net/"
                />

      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="TableStorageRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookieTimeout="30"
                     cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration = "true"
                     cookieProtection="All" >
      <providers>
        <clear/>
        <add name="TableStorageRoleProvider"
             type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageRoleProvider"
             description="Role provider using table storage"
             allowInsecureRemoteEndpoints="true"
             applicationName="YourAppName"
             accountName="youracctname"
             sharedKey="xxxxxx"
             tableServiceBaseUri="http://youracctname.table.core.windows.net/"
                />
      </providers>
    </roleManager>
    <sessionState mode="Custom" customProvider="TableStorageSessionStateProvider">
      <providers>
        <clear />
        <add name="TableStorageSessionStateProvider"
             type="Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
             allowInsecureRemoteEndpoints="true"
             applicationName="YourAppName"
             accountName="youracctname"
             sharedKey="xxxxxx"
             tableServiceBaseUri="http://youracctname.table.core.windows.net/"
             blobServiceBaseUri="http://youracctname.blob.core.windows.net/"
             />
      </providers>
    </sessionState>

I struggled a bit to get this to work but changing the passwordFormat to Clear made everything work so I have assumed that there’s a bug with the Hashed passwords currently.

By the way, I used this tool http://azurestorageexplorer.codeplex.com/ with great success for confirming whether data was being written/read correctly and whether the tables were being created successfully.

21
Feb
10

Azure + Silverlight 4 + RIA Services + MVC2 (Part 2)

by Peter Daukintis

Ok, with Azure out of the equation until .NET 4 is supported I will turn my attention first to work out how to achieve data storage in the cloud whilst considering the overall architecture.

Firstly, I added an empty Domain Service Class by selecting the web hosting project and selecting Add New Item…

AddDomainServiceClass

This results in the following dialog:

EmptyDomainServiceClassDlg

From which I elected to choose <empty domain service class> since I wanted my storage to be hosted on Azure Tables which is not supported out of the box.

This generates an empty domain service class, which I fleshed out a little with the following code:

    [EnableClientAccess()]
    public class TestDomainService : DomainService
    {
        private readonly ITestEntityRepository _testEntityRepository;

        public TestDomainService(ITestEntityRepository repository)
        {
            _testEntityRepository = repository;
        }

        public IQueryable<TestEntity> GetEntities()
        {
            return _testEntityRepository.GetTestEntities();
        }

        [Invoke]
        public void AddTestEntity(TestEntity testEntity)
        {
            _testEntityRepository.AddTestEntity(testEntity);
        }
    }
}

which is about as simple as I could make it whilst introducing a repository interface to support testability and adhere to a clear separation of concerns. Leaving the code like this will result in problems as the RIA services code generation layer requires a default constructor for the domain service class. the intention is to inject the concrete repository at runtime using an IOC container.  I used Unity as my IOC container of choice. the mechanism provided as a hook for creation of domain service classes is the IDomainServiceFactory interface (see http://msdn.microsoft.com/en-us/library/system.web.domainservices.idomainservicefactory(VS.91).aspx). You can set the DomainService.Factory property to a concrete implementation of your own IDomainServiceFactory interface like the following:

    public class DomainServiceFactory : IDomainServiceFactory
    {
        public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context)
        {
            var service = Global.IocContainer.Resolve(domainServiceType) as DomainService;
            if (service != null)
            {
                service.Initialize(context);
            }
            return service;
        }

        public void ReleaseDomainService(DomainService domainService)
        {
            domainService.Dispose();
        }
    }

Now, this ensures that Unity will resolve the dependencies on the domain service context. So we just need to wire this in and register our dependencies with Unity and we should be back in business.

        protected void Application_Start(object sender, EventArgs e)
        {
            if (IocContainer == null)
                IocContainer = new UnityContainer();
            DomainService.Factory = new DomainServiceFactory();

            IocContainer.RegisterType<TestDomainService>();
            IocContainer.RegisterType<ITestEntityRepository, TestEntityRepository>();
        }

Now that takes care of some of the plumbing, but what about the actual implementation for the Azure Table Storage?

Well, borrowing some code from here http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/efdc0bcc-918c-4034-be1d-ecb13a601e7e gives us an idea of how to implement the repository;

    public class TestEntityRepository : ITestEntityRepository
    {
        private static readonly TestDomainContext Ctx;

        static TestEntityRepository()
        {
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
                                                                 configSetter(ConfigurationManager.AppSettings[configName]));

            CloudStorageAccount account = CloudStorageAccount.FromConfigurationSetting("<your name here>");

            var tableClient = new CloudTableClient(account.TableEndpoint.ToString(), account.Credentials);
            tableClient.CreateTableIfNotExist("TestEntities");
            Ctx = new TestDomainContext(account.TableEndpoint.ToString(), account.Credentials);
        }

        public IQueryable<TestEntity> GetTestEntities()
        {
            return Ctx.TestEntities;
        }

        public void AddTestEntity(TestEntity testEntity)
        {
            Ctx.AddTestEntity(testEntity.Name, testEntity.Age);
        }
   }

Where the TestEntity looks like this:

    public class TestEntity : TableServiceEntity
    {
        public TestEntity()
        { }

        public TestEntity(string partitionKey, string rowKey)
            : base(partitionKey, rowKey)
        { }

        [Key]
        public override string PartitionKey
        {
            get { return base.PartitionKey; }
            set { base.PartitionKey = value; }
        }

        [Key]
        public override string RowKey
        {
            get { return base.RowKey; }
            set { base.RowKey = value; }
        }

        public string Name { get; set; }
        public int Age { get; set; }
    }

And the TestDomainContext used by the Concrete repository looks like this:

public classTestDomainContext :TableServiceContext
   
{
       
publicTestDomainContext(string baseAddress, StorageCredentials credentials)
            :
base(baseAddress, credentials)
        {
        }

        public IQueryable<TestEntity> TestEntities
       
{
           
get { return CreateQuery<TestEntity>("TestEntities"); }
        }

        public void AddTestEntity(string name, int age)
        {
           
var c = new TestEntity((DateTime.MaxValue.Ticks - DateTime.Now.Ticks).ToString(), Guid.NewGuid().ToString())
            {
               
Name = name,
               
Age = age
           
};
           
AddObject("TestEntities", c);
   
        SaveChanges();
        }
    }

I just needed to set up the account info in my web.config file to give a working solution:

      <add key="your_key" value="DefaultEndpointsProtocol=https;AccountName=your_acct_name;AccountKey=”xxxxxxxxxx" />

That’s it for now – in the next post I will try to configure the application to use azure table storage for authentication….

19
Feb
10

Azure + Silverlight 4 + RIA Services + MVC2 (Part 1)

by Peter Daukintis

The original idea for this post was to see whether this combination of technologies played well together. Whilst the development tools seem to support this scenario I believe that there is, as yet, no support for .NET 4 on Azure (see When .NET 4.0 will be available in Azure ?), so some of this discussion is hypothetical. The first post outlines setting up the development environment.

Anyway, first I began by doing what seemed obvious:

Having installed the required SDKs and tools for SL4, RIA services and Azure I started VS2010 (Beta 2) and created a new Windows Azure Cloud Service project, chose to add an MVC 2 Web Role by right-clicking on the Web Role folder of the newly created cloud project, added default unit test project and tried running this and it all ran fine.

Then, I added a Silverlight 4 project to be hosted in the MVC app. I did this by adding a new project to the solution, choosing Silverlight Navigation Application Project. From the options presented I chose to host the new app in the existing MVC app and I then set the aspx page which was added to the MVC project as the start-up page. Hit F5 and the build system produces this error

Error    2    Cloud Service projects currently support Roles that run on .NET Framework version 3.5.  Please set the Target Framework property in the project settings for this Role to .NET Framework 3.5.  

So, I can’t get my app running in the Azure Development Fabric due to my dependencies on .NET 4 (I was hoping that the development tools may support this scenario).

I decided to prepare the app for when this would be possible and so turned my attention towards RIA Services. It was at this stage that I realised that what I wanted to actually do was to create a Silverlight Business Application rather than a navigation application. This VS template is available when you install the RIA Services Beta. However, I had previously experimented with RIA Services using VS2008 and the corresponding RIA Services installs do not live together (at least, according to the installer as it insists that you remove any previous versions).  So, backing up a little bit, I uninstalled the VS2008 version and re-installed for 2010. I then ran through the above procedure again but chose the Business Application template rather than the navigation one.

SLBusAppTemplate

Having worked through the steps again, the result was very similar except for the addition login control:

SLBusinessApp 

So, hopefully I am now where I wanted to be, which was to have a solution that can be hosted easily in the cloud (when Azure supports .NET 4) with a development environment in which I can carry out some rapid, test-driven development.

14
Oct
09

Azure Management API

by Peter Daukintis

Disclaimer – the code shown below is not of high quality, does not have any error handling and is shown for educational purposes only.

Having hosted an experimental application on the Azure CTP since PDC ‘08 I decided it was time that I stopped putting myself through the process of having to manually upload changes via the Azure Developer Portal. Luckily for me, the Azure Team accelerated my progress by releasing the Azure Management API (see http://blogs.msdn.com/windowsazure/archive/2009/09/17/introducing-the-windows-azure-service-management-api.aspx for an introduction and the docs can be found here http://msdn.microsoft.com/en-us/library/ee460799.aspx).

My current build system uses CruiseControl.NET and when I kick off a ‘deployment’ build currently I have an MSBuild task that copies the deployment files (.csdef and .cspkg) to Azure Storage. This was an interim step that allows me to keep backups in the cloud and also to be able to select and deploy them easily via the Developer Portal. So, the next step was to develop another MSBuild task which accessed the new management APIs to enable a deploy. (An alternative to this would be to take the approach outlined here http://blogs.msdn.com/domgreen/archive/2009/09/29/deploying-to-the-cloud-as-part-of-your-daily-build.aspx which uses the csmanage.exe command line tool provided by the Azure Team).

Creating an MSBuild task is very straightforward and is documented here http://msdn.microsoft.com/en-us/library/t9883dzc.aspx and there are plenty of other online resources describing the process.

So, on to the code; this is the outline of the MSBuild task, it uses the AzureAccount class to do all of the real work:

public classDeployToAzureTask : Task
{
    [Required]
    public stringPackageUri { get; set; }

    [Required]
    public stringConfigUri { get; set; }
   
    public override bool Execute()
    {
        AzureAccount acct = newAzureAccount("cert.cer", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX");

        if(Uri.IsWellFormedUriString(PackageUri, UriKind.Absolute) == true&&
            Uri.IsWellFormedUriString(ConfigUri, UriKind.Absolute))
        {
            acct.Upgrade("MyServiceName", "staging", newUri(PackageUri), newUri(ConfigUri));
            return true;
        }

        return false;
    }
}

 

Some things need to be explained:

The “cert.cer” string is the path location of a self-signed certificate which can be created using IIS or generated using the makecert command line tool as follows:

makecert -r -pe -a sha1 -n "CN=Windows Azure Authentication Certificate" -ss My -len 2048 -sp "Microsoft Enhanced RSA and AES Cryptographic Provider" -sy 24 mycert.cer

and uploaded to your Azure account using the Developer Portal Account tab:

APICert  

The constructor for the AzureAccount class takes a local path to your self-signed certificate and also your Azure account subscription ID (also on the Account tab of the Azure Developer Portal).

The Upgrade call takes the name of your service, a string which is either ‘staging’ or ‘production’ and uri’s to the input packages (since I have these uploaded to Azure Storage).

So, now to the important part…

The upgrade call will replace an existing running hosted service with your new one (when upgrading the staging server this leaves the url exactly the same as before i.e. with the same guid which can be useful if you don’t want to keep publishing the deployed url).

public string Upgrade(stringserviceName, stringdeploymentSlot, UripackageURI, UricfgURI)
{
    // Download the cfg file to convert to base 64..
  
WebClient wc = newWebClient();
    stringtempfile = System.IO.Path.GetTempFileName();
    wc.DownloadFile(cfgURI, tempfile);

    byte[] bytes = File.ReadAllBytes(tempfile);
    stringbase64Str = Convert.ToBase64String(bytes);

    if(base64Str != null)
    {
        stringlbl = DateTime.Now.ToString("MM-dd-yyyyTHH-mm-ss");
        System.Text.UTF8Encodingenc = newSystem.Text.UTF8Encoding();
        byte[] lblBytes = enc.GetBytes(lbl);
        lbl = Convert.ToBase64String(lblBytes);

        XNamespace ns = XNamespace.Get("http://schemas.microsoft.com/windowsazure&quot;);
        XNamespace nsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance&quot;);

        XDocument doc = newXDocument(newXDeclaration("1.0", "utf-8", "no"),
                    newXElement(ns + "UpgradeDeployment",
                    newXElement(ns + "Mode", "auto"),
                    newXElement(ns + "PackageUrl", packageURI.ToString()),
                    newXElement("RoleToUpgrade", newXAttribute(nsi + "nil", "true")),
                    newXElement(ns + "Configuration", base64Str),
                    newXElement(ns + "DeploymentLabel", lbl)));

        Uriuri = newUri(_baseUri, _subscriptionId + "/services/hostedservices/"+ serviceName +
            "/deploymentslots/"+ deploymentSlot.ToLower() + "/action=upgrade");

        CreateHttpRequest(uri, "POST", _cert, _timeout, doc);
    }

    return null;
}

 

So, this function downloads the configuration file from storage and converts it’s contents to base64 as required by the API. Then it bundles all of the inputs up into xml format to be posted to the upgrade api which is documented here http://msdn.microsoft.com/en-us/library/ee460793.aspx. When I implemented this exactly as stated in the documentation I couldn’t get the call to succeed so I used Fiddler to check a similar request made by using csmanage.exe and modified the data I was posting based on this. So, there may be some minor inconsistencies between my code and the documentation but this code works at the time of posting.

One thing to note is that if you have Fiddler running on your machine when these API calls are made they won’t work as Fiddler won’t know to use your client certificate when it forwards your request. I guess there is a way to configure Fiddler to allow the calls to be made with the correct certificate.

The final piece of code required to get this all working is to create the request and check the response:

public HttpWebRequest CreateHttpRequest(Uriuri, stringhttpMethod,
    X509Certificate2accessCertificate, TimeSpan timeout, XDocument postData)
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
    request.Timeout = (int)timeout.TotalMilliseconds;
    request.ReadWriteTimeout = (int)timeout.TotalMilliseconds * 100;
    request.Method = httpMethod;
    request.ClientCertificates.Add(accessCertificate);
    request.Headers.Add("x-ms-version", "2009-08-08");
    request.ContentType = "application/xml";
    if(httpMethod.ToLower() == "post")
    {
        PostWrapper wrapper = newPostWrapper();
        wrapper.postData = postData.ToString();
        wrapper.Request = request;
        request.BeginGetRequestStream(newAsyncCallback(ReadCallback), wrapper);
    }
    returnrequest;
}

private voidReadCallback(IAsyncResult asynchronousResult)
{
    PostWrapper data = (PostWrapper)asynchronousResult.AsyncState;
    HttpWebRequest request = data.Request;

    // End the operation.
  
StreampostStream = request.EndGetRequestStream(asynchronousResult);

    stringsData = data.postData.ToString();
    System.Text.UTF8Encodingenc = newSystem.Text.UTF8Encoding();
    byte[] stringBytes = enc.GetBytes(sData);
   
    postStream.Write(stringBytes, 0, stringBytes.Length);
    postStream.Close();

    request.BeginGetResponse(newAsyncCallback(ResponseCallback), request);
}

private voidResponseCallback(IAsyncResult asynchronousResult)
{
    HttpWebRequest req = asynchronousResult.AsyncState asHttpWebRequest;
    if(req != null)
    {
        WebResponse resp = req.EndGetResponse(asynchronousResult);
        //resp.
      
stringtrackingId = resp.Headers.Get("x-ms-request-id");

        startPollingOperation(trackingId);
    }
}

 

The response received in the ResponseCallback method returns an ID string which you can then use to track the status of the operation. I haven’t got this bit working yet so haven’t provided a definition for startPollingOperation. This is not necessary for my build task as I am just happy to start the operation rolling. I am also developing a wpf application that uses this code and I will probably update it to call other parts of the API as I need them.

Technorati Tags: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Windows Live Tags: Azure,Management,Disclaimer,code,error,Developer,Portal,Team,archive,introduction,library,system,CruiseControl,deployment,MSBuild,task,files,Storage,APIs,tool,AzureAccount,DeployToAzureTask,PackageUri,ConfigUri,Execute,cert,XXXXXXXX,XXXX,XXXXXXXXXXXX,Absolute,Upgrade,MyServiceName,Some,path,location,self,certificate,Authentication,Microsoft,Cryptographic,Provider,account,subscription,production,packages,server,Download,WebClient,GetTempFileName,DownloadFile,File,ReadAllBytes,Convert,DateTime,Text,GetBytes,XNamespace,XMLSchema,instance,XDocument,XDeclaration,XElement,UpgradeDeployment,Mode,PackageUrl,RoleToUpgrade,XAttribute,Configuration,DeploymentLabel,_baseUri,_subscriptionId,services,ToLower,action,CreateHttpRequest,POST,_cert,_timeout,contents,documentation,Fiddler,data,machine,client,piece,response,HttpWebRequest,TimeSpan,timeout,Create,TotalMilliseconds,ReadWriteTimeout,Method,ClientCertificates,Headers,version,ContentType,PostWrapper,wrapper,Request,BeginGetRequestStream,AsyncCallback,ReadCallback,IAsyncResult,AsyncState,operation,Stream,EndGetRequestStream,Write,Length,Close,BeginGetResponse,ResponseCallback,WebResponse,EndGetResponse,status,haven,definition,purposes,backups,inconsistencies,blogs,msdn,windowsazure,aspx,csmanage,acct,makecert,serviceName,deploymentSlot,cfgURI,tempfile,byte,bytes,lblBytes,httpMethod,accessCertificate,postData,asynchronousResult,postStream,sData,stringBytes,resp,trackingId,startPollingOperation




Follow

Get every new post delivered to your Inbox.