Home
About
Contact
Monday, February 15, 2010

In part 1 I explained why I needed a load balancer that was capable of doing smart balancing decisions using more than just IPs and why I decided to use IIS7 and Application Request Routing (ARR). In this part I will give a detailed explanation of how to setup ARR on Windows Server 2008 R2 Web Server Core.

Server Core provide the following benefits over traditional installations according to Microsoft:

  • Reduced maintenance
  • Reduced attack surface
  • Reduced management
  • Less disk space required

I concluded that the above points is quite important for a load balancer, as you don’t want it to spend its resources on anything else than load balancing.

In this guide I will walk you through the steps needed to install Windows Server 2008 Web Server Core. Secondly I will show you how to create the necessary scripts to automate about 99% of the installation and configuration of ARR.

Before we dig deep, here’s a short description of the setup I used for my ARR environment:

Two Web Servers with:

  • 3 websites running both SSL and normal HTTP
  • Each website needed its own IP
  • Each website needed its own SSL certificate

ARR Server:

  • In order to avoid the “clients NAT’ed behind one IP” problem, I needed to configure ARR Server Affinity to UseCookie.
  • As for the Load Balancing Algorithm I used Weighted Round Robin (you should look into the other alternatives that suite your needs)
  • The ARR server is responsible for distributing traffic to two web servers mentioned above

All of the above can of course be changed in the scripts that I’ll be showing later to suite your configuration needs. Below is an illustration of the infrastructure:

image

Installing Windows Server 2008 R2 Web Server Core:

  1. Install Windows Server 2008 R2 Web - Server Core
  2. Set password for admin (when prompted)
  3. Rename server:
    NETDOM renamecomputer %computername% /newname:[nameOfServer]
  4. Restart:
    shutdown /r /t 0
  5. Set static IP:
    netsh interface ipv4 set address "Local Area Connection" static [IP] [Subnet] [Gateway]
  6. Set Primary DNS server:
    netsh interface ipv4 add dnsserver "Local Area Connection" [IP]
  7. Set Secondary DNS server:
    netsh interface ipv4 add dnsserver "Local Area Connection" [IP] index=2
  8. If you want the server to join a domain:
    netdom join %computername% /domain:[domainname] /userd:[username] /passwordd:*
  9. Restart:
    shutdown /r /t 0
  10. If you want to enable Remote Desktop:

    For Vista/Win7/2008 clients:
    cscript %windir%\system32\SCRegEdit.wsf /ar 0

    For earlier clients:
    cscript %windir%\system32\SCRegEdit.wsf /cs 0

    For both new and earlier clients run both of the above
  11. If you want to allow remote MMC management (e.g. to simplify managing users etc):
    netsh advfirewall firewall set rule group="Remote Administration" new enable=yes
  12. Activate Windows:
    start /w slmgr.vbs –ipk [key]
    start /w slmgr.vbs –ato

Now the server is ready for ARR installation and configuration, but since the OS is a server core, creating some scripts to automate this procedure is very helpful. Next I will show you the scripts I created and used, which hopefully will make this task easier for you than for me :-) I’ve made all the files and scripts available in this zip file.

Creating script for installing SSL certificates (do this on some client computer, not the ARR Server):

Note: You can skip this section (except step 1 and 2) if you’re not using SSL.

  1. Create a folder called ARRInstall
  2. In the ARRInstall folder, create a new folder called Utils
  3. Download capicom_dc_sdk.msi and place MSI in the Utils folder
  4. Download winhttpcertcfg.msi and install with default options on a client computer
  5. Browse to C:\Program Files (x86)\Windows Resource Kits\Tools\ and copy winhttpcertcfg.exe into your Utils folder
  6. Create a folder called Certificates in your ARRInstall folder
  7. The above folder must contain all your certificates (both with and without private keys). For my setup this looks like this:

    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
  8. Copy the script below, read comments in script and modify accordingly. Then save the script as _SetupCertificates.cmd in the ARRInstall folder:
    @echo off
    
    echo Installing CAPICOM...
    
    echo.
    
    msiexec /qn /i "%~dp0Utils\capicom_dc_sdk.msi"
    
    echo Removing existing certificate from store...
    
    REM Example:
    
    REM certutil -delstore Root "blog.torresdal.net"
    
    certutil -delstore Root "[certificate name]"
    
    echo Removing SSL certificate from IIS...
    
    netsh http delete sslcert ipport=0.0.0.0:443
    
    echo Installing certificates...
    
    echo.
    
    REM Example:
    
    REM certutil -f -addstore Root "%~dp0Certificates\blog.torresdal.net.cer"
    
    certutil -f -addstore Root "%~dp0Certificates\[certificate name].cer"
    
    IF EXIST "%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK" (
    
        SET capicompath="%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    
        SET cscript=%windir%\system32\cscript.exe
    
    )
    
    IF EXIST "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK" (
    
        SET capicompath="%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    
        SET cscript=%windir%\syswow64\cscript.exe
    
        ECHO Setting up CAPICOM for 64 bits environment...
    
        copy /y "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Lib\X86\capicom.dll" %windir%\syswow64
    
        %windir%\syswow64\regsvr32.exe /s %windir%\syswow64\capicom.dll
    
    )
    
    REM Example:
    
    REM %cscript% /nologo %capicompath% delete -l LM -subject "blog.torresdal.net" -noprompt
    
    %cscript% /nologo %capicompath% delete -l LM -subject "[certificate name]" -noprompt
    
    REM Example:
    
    REM %cscript% /nologo %capicompath% import -l LM "%~dp0Certificates\blog.torresdal.net.pfx" "somePassword"
    
    %cscript% /nologo %capicompath% import -l LM "%~dp0Certificates\[certificate name].pfx" "[password]"
    
    REM Example:
    
    REM "%~dp0Utils\winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s blog.torresdal.net -a "IIS_IUSRS"
    
    "%~dp0Utils\winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s [certificate name] -a "IIS_IUSRS"
    
    echo.
    
    echo ============================
    
    echo Certificates Setup finished!
    
    echo ============================
    
    REM pause
    
    :end
  9. Your folder structure should now look like this:
    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
      |-- Utils
            |-- capicom_dc_sdk.msi
            |-- winhttpcertcfg.exe
      |-- _SetupCertificates.cmd

Create script for installing and configuring ARR:

  1. Download the x64 installer for ARR from the ARR website: http://www.iis.net/expand/ApplicationRequestRouting
  2. Copy the downloaded file (ARRv2_setup_x64.EXE) into the Utils folder
  3. Download IIS7Util.exe which I’ve made available for you on my site. (The source code can be found at the foaf-ssl-dotnet project. Just browse code and search for “iis7util”, to make it clear where I got it from :-))
  4. Copy the IIS7Util.exe into the Utils folder
  5. Copy the script below, read comments in script and modify accordingly. Then save the script as InstallARR.cmd in the ARRInstall folder. You should then have this file structure:

    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
      |—Utils
            |-- ARRv2_setup_x64.EXE
            |-- capicom_dc_sdk.msi
            |-- IIS7Util.exe
            |-- winhttpcertcfg.exe
      |-- _SetupCertificates.cmd
      |-- InstallARR.cmd

    Note: If you’re not using SSL, comment out this line in your script:
    call %~dp0_SetupCertificates.cmd

    @echo off
    
    REM =====================
    
    REM 	CONFIGURATION
    
    REM =====================
    
    REM =============================================
    
    REM IP's for the different sites on the LB Server
    
    REM =============================================
    
    SET Site1IPNLB=10.0.0.51
    
    SET Site2IPNLB=10.0.0.52
    
    SET Site3IPNLB=10.0.0.53
    
    REM =============================
    
    REM IP's for back end web servers
    
    REM =============================
    
    SET Site1IPWeb01=10.137.13.61
    
    SET Site2IPWeb01=10.137.13.62
    
    SET Site3IPWeb01=10.137.13.63
    
    SET Site1IPWeb02=10.137.13.71
    
    SET Site2IPWeb02=10.137.13.72
    
    SET Site3IPWeb02=10.137.13.73
    
    REM ==============================
    
    REM Host names for different sites
    
    REM ==============================
    
    SET Site1HostName=site1.torresdal.net
    
    SET Site2HostName=site2.torresdal.net
    
    SET Site3HostName=site3.torresdal.net
    
    REM ==================================
    
    REM Name of Server Farms for each site
    
    REM ==================================
    
    SET ARRServerFarm1=Site1
    
    SET ARRServerFarm2=Site2
    
    SET ARRServerFarm3=Site3
    
    REM ============================
    
    REM File locations for web sites
    
    REM ============================
    
    SET Site1FileLoc=C:\%ARRServerFarm1%
    
    SET Site2FileLoc=C:\%ARRServerFarm2%
    
    SET Site3FileLoc=C:\%ARRServerFarm3%
    
    REM ==========
    
    REM AppCmd.exe
    
    REM ==========
    
    SET AppCMD=%windir%\system32\inetsrv\appcmd.exe
    
    REM =========================
    
    REM	INSTALLATION
    
    REM =========================
    
    Echo Installing IIS...
    
    start /w pkgmgr /l:log.etw /iu:IIS-WebServerRole;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI;NetFx2-ServerCore;NetFx2-ServerCore-WOW64;IIS-ManagementService
    
    Echo Enabling remote management of IIS...
    
    reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WebManagement\Server /v EnableRemoteManagement /t REG_DWORD /d 1 /f
    
    sc config WMSVC start= auto
    
    Echo Installing Application Request Routing (ARR)...
    
    net stop was /y
    
    net stop wmsvc /y
    
    "%~dp0utils\ARRv2_setup_x64.EXE" /Q
    
    net start was
    
    net start wmsvc
    
    Echo Disable Idle Timeout on Application Pool...
    
    %AppCMD% set apppool "DefaultAppPool" -processModel.idleTimeout:"00:00:00" /commit:apphost
    
    %AppCMD% set config -section:system.applicationHost/applicationPools /[name='DefaultAppPool'].recycling.periodicRestart.time:"00:00:00" /commit:apphost
    
    Echo Installing certificates...
    
    call %~dp0_SetupCertificates.cmd
    
    Echo Adding aditional IPs for web sites...
    
    netsh interface ipv4 add address "Local Area Connection" %Site1IPNLB% 255.255.255.0
    
    netsh interface ipv4 add address "Local Area Connection" %Site2IPNLB% 255.255.255.0
    
    netsh interface ipv4 add address "Local Area Connection" %Site3IPNLB% 255.255.255.0
    
    Echo Creating folders for web sites...
    
    md %Site1FileLoc%
    
    md %Site2FileLoc%
    
    md %Site3FileLoc%
    
    Echo Creating web sites in IIS...
    
    %AppCMD% add site /name:%site1HostName% /bindings:"http/%Site1IPNLB%:80:,https/%Site1IPNLB%:443:" /physicalPath:"%Site1FileLoc%"
    
    %AppCMD% add site /name:%site2HostName% /bindings:"http/%Site2IPNLB%:80:,https/%Site2IPNLB%:443:" /physicalPath:"%Site2FileLoc%"
    
    %AppCMD% add site /name:%site3HostName% /bindings:"http/%Site3IPNLB%:80:,https/%Site3IPNLB%:443:" /physicalPath:"%Site3FileLoc%"
    
    Echo Adding farms and servers to ARR...
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%'].[address='%Site1IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%'].[address='%Site1IPWeb02%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%'].[address='%Site2IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%'].[address='%Site2IPWeb02%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%'].[address='%Site3IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%'].[address='%Site3IPWeb02%']" /commit:apphost
    
    REM ==============================================================================
    
    REM ALERT!: REMEMBER THAT SSL RULES FOR EACH SITE MUST BE BEFORE THE HTTP RULES!!!
    
    REM 	    E.g. 1) Rules for Site1 SSL
    
    REM              2) Rules for Site1 HTTP
    
    REM		 3) Rules for Site2 SSL
    
    REM		 4) Rules for Site2 HTTP
    
    REM		 5) etc.
    
    REM
    
    REM	    If we had switched 1 and 2, it would match on HTTP first, and would
    
    REM	    have redirected to a non SSL site, resulting in SSL offloading.
    
    REM
    
    REM	    If SSL offloading is the wanted behaviour, only the HTTP rule is 
    
    REM	    nessesary.
    
    REM ==============================================================================
    
    echo Adding rewriting rules to ARR...
    
    %AppCMD% clear config -section:system.webServer/rewrite/globalRules
    
    REM Site1 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site1HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm1%/{R:0}" /commit:apphost
    
    REM Site1 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site1HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm1%/{R:0}" /commit:apphost
    
    REM Site2 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site2HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm2%/{R:0}" /commit:apphost
    
    REM Site2 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site2HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm2%/{R:0}" /commit:apphost
    
    REM Site3 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site3HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm3%/{R:0}" /commit:apphost
    
    REM Site3 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site3HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm3%/{R:0}" /commit:apphost
    
    REM ===============
    
    REM Server Affinity
    
    REM ===============
    
    Echo Adding Server Affinity...
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm1%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm2%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm3%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    REM ========================
    
    REM Load Balancing Algorithm
    
    REM ========================
    
    Echo Adding Load Balancing Algorithm...
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm1%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm2%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm3%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost

Installing Application Request Routing:

  1. From the ARR server connect to your client containing the script files:
    net use [some drive letter]: \\clientComputerName\[drive on client]$ /user:domain\user
    Example:
    net use r: \\myClient\c$ /user:torresdal\jon
  2. Make a directory on the server to copy the files to:
    E.g.: md c:\temp\arr
  3. Copy the ARRInstall folder from your client to C:\temp\arr on your server
  4. Run InstallARR.bat, watch for errors and wait for it to finish
  5. Install Remote IIS Manger on a PC that will administrate IIS and connect to the ARR server: http://www.iis.net/expand/IISManager
  6. In Internet Information Services Manager connected to ARR do:
    1. Select Sites->Site1
    2. Click Bindings (upper right corner)
    3. Click https –> Edit
    4. Select proper certificate
    5. Repeat for all other sites
  7. Under Sites:
    1. For each site that require SSL:
      1. Click SSL Settings
      2. Check Require SSL
  8. Start IIS on ARR server:
    iisreset /start
  9. Using Internet Information Services Manager:
    Stop “Default Web Site”
  10. You’re done!

I hope this helped in making the installation and configuration of the ARR server easier, and that my scenario is applicable to others except me :-) Let me know if I can help with questions or if you find any errors.

Next time I will talk about how to avoid the ARR server being the Single Point of Failure.

Monday, February 15, 2010 8:00:00 AM (W. Europe Standard Time, UTC+01:00)
Wednesday, February 10, 2010

image A few weeks back I had to solve a performance problem at work. For some of our applications most of our users are NAT’ed behind the same IP, making the default load balancer (NLB) in Windows direct the majority of all traffic to one server. NLB in Windows work on layer 3 (network layer) in the OSI model (that thing you learned at uni), meaning we can only take advantage of IP stuff. So usually you use what’s often called Sticky Sessions (Single Affinity) to keep track of which IP’s got redirected to which server, and keep doing that from that point on for that IP. This was the setup we had.

You can work around that problem by disabling Sticky Sessions, but it might influence performance and could give you unwanted consequences. As an example, if you use ASP.NET Web Forms you will probably run into an issue with ViewState and possibly session issues. For SSL however (which was the case for us), Sticky Session is not recommended.

Other “smarter” load balancers work on layer 7 (application layer), providing us with a much bigger toolbox to inspect traffic and make smarter choices for where to redirect traffic. So I started to look for a load balancer on layer 7. The obvious first choice was hardware LB. This is often the quickest solution, but also the most expensive. I looked at Cisco’s Application Control Engine Module (ACE) and F5 BigIP, but the price was and issue as well as the lack of people with know-how inside our organization of how to configure them.

My next option was setting up a Linux server running Apache and LB, but then I came across a Microsoft module on IIS7: Application Request Routing (ARR). I found some really good documentation and it looked quite easy to set up. Since I (and others in my organization) are used to working with IIS, this seamed to be worth investigating.

In my next post I’ll go trough all the details of setting up ARR on Windows 2008 R2 Server Core. Everything from installing and configuring the OS to automate installation of ARR by scripts.

Wednesday, February 10, 2010 7:00:00 AM (W. Europe Standard Time, UTC+01:00)
Tuesday, February 09, 2010

image I’m happy to say I was invited by Microsoft to join their MSDN Live tour in Norway this spring. I’ll be talking about Windows Identity Foundation (WIF) (used to be Geneva) which I find to be at great help simplifying authentication and authorization in small shops as well as in the enterprise.

I’ll be showing how you can take advantage of Claims (link is a PDF) in your applications today and why that is a good idea, how to easily integrate with Active Directory using Active Directory Federation Services (ADFS), how to create a custom Security Token Service (STS) and cover parts of the tiny topic of: how to do Federation in the enterprise :-)

Remember that the concepts around WIF, like Claims and STS, is nothing new and is not something that Microsoft has invented. It’s been around for many years and are supported on many platforms as well as programming languages.

Personally I’m quite excited about this new framework, cause it particularly helps us at Frende solve some pain points we’ve had to tackle around authentication with a lot of different sign-on methods and applications, and ease the use of SSO. We can now delete a lot of code, since WIF takes care of a lot of the plumbing we previously had to do ourselves. Less code to maintain is always good!

For more information about the agenda, have a look at Rune Grothaug’s blog: http://blogs.msdn.com/grothaug/pages/msdn-live-april-2010-en-fest-for-utviklere.aspx

I expect the official MSDN Live and TechNet site to be updated with the spring agenda very soon: http://www.microsoft.no/live/

The cities and dates are:

Stavanger: 16th of April
Trondheim: 20th of April
Bergen: 23rd of April
Oslo: 26th of April

Tuesday, February 09, 2010 10:02:26 AM (W. Europe Standard Time, UTC+01:00)
Thursday, January 14, 2010

logo_qcon Going to QCon London? I am and a bunch of my friends are too! Just a heads up that the early bird is about to expire this Friday.

If you haven’t been to QCon before, I can really recommend it. What I find especially attractive by this conference is its various tracks that should satisfy the most demanding devs and architects, and of course not to mention the speaker list (which is still growing). Here’s a few selected speakers from my point of view:

  • Dan North
  • Floyd Marinescu
  • Jim O. Coplien
  • Joe Armstrong
  • Jon Skeet
  • Kevlin Henney
  • Michael T. Nygard
  • Ola Bini
  • Ayende (Oren Eini)
  • Rod Johnsen
  • Ryan Slobojan
  • Stefan Tilkov
  • Steve Freeman
  • Udi Dahan
  • Ulf Wiger

And here’s the tracks:

  • Architectures You've Always Wondered About
  • Dev and Ops: A single team
  • Functional programming
  • Non-Relational DBs & Web Oriented Data
  • Software Craftsmanship
  • Solution Track: Wednesday
  • 2015 Software Development
  • Agile Evolution
  • AlphaGeeks on .NET
  • Cloud Solutions
  • Irresponsible Architectures and Unusual Architects
  • Solutions Track: Performance and ScalabilityBrowser as a Platform
  • Cool Stuff with Java
  • How do you test that?
  • SOA 2010
  • The Concurrency Challenge

Hope to see you in London March 10-12 (March 8-9 for tutorials).

Thursday, January 14, 2010 8:13:05 PM (W. Europe Standard Time, UTC+01:00)
Sunday, August 23, 2009

imageEven though I don’t develop software in SharePoint, this blog post by Lee Richardson reflect my thoughts and worries about SharePoint development.

The essence of his post is in this paragraph:

But the power given to end users makes rigor and good design extremely hard for developers because the production machine you deployed to last month may look completely different now that you’re ready to redeploy. And Microsoft makes good design even harder with an inflexible API. Critical classes like SPSite (think SqlConnection) contain no public constructor, rendering them completely unmockable (unless you’re willing to spend $450 per developer for some TypeMock Isolator magic). And vital classes like SPList (think DataSet) are marked final, crippling your ability to make nice strongly typed entities in your architectures.

Lee proposes some techniques to use that you should read in his post, but it’s half baked and not good enough in my opinion. The things he suggests (which is usually taken for granted on any other project) is made really hard to do by MS. Should MS rethink the way SharePoint is architected for the sake of developers to ease maintenance, improve code quality and basically allow developers working with ShapePoint to be craftsmen? Or is the dynamics of the product given to the end user so good that it’s worth all the extra efforts?

Sunday, August 23, 2009 12:46:38 AM (W. Europe Daylight Time, UTC+02:00)
Monday, August 03, 2009

It's tempting to just leave this blog post with that statement only :-) I will however explain this a bit further for those of you who either are forced to write comments (like by your boss or a policy at your company), or actually believe a lot of comments in code increase readability and ease maintenance.

I'm not trying to be sarcastic, I just believe 100% in code and not in comments. In .NET and most other OO languages there are two types of comments. The first type is the one you write in your code to explain what your code does. Like this:

//Calculate interest
double amount 
    = balance * Math.Pow(1 + (annualPercentage / 100) / 365, days)
      - balance;

How do you replace this comment with code? What about this:

double amount = CalculateInterest(balance, annualPercentage, days);

Whenever you come across comments like the above, I encourage you to refactor by replacing comments with code. Often you don't even have to extract a method like above, but just give better names to variables.

The second type of comments is the ones you use to generate API documentation:

/// <summary>
/// Calculate interest
/// </summary>
/// <param name="balance">Current balance of the account</param>
/// <param name="annualPercentage">Annual percentage</param>
/// <param name="days">Days to calculate interest for</param>
/// <returns>Interest amount</returns>
public double CalculateInterest(double balance, 
                                double annualPercentage, 
                                int days)
{

Almost on every project I've been on we've had these comments/documentation. Also, on the same projects they've never been used for anything useful. I've actually forced devs to do this myself! If you're creating a product/framework to be used by other devs, writing this type of documentation makes sense. If you don't, it makes no sense! I used to do this just to satisfy my own satisfaction of generating a chm file and see that all my methods and classes was documented. That was about it. I never used it once! It's much easier to look in the code than to look at the API doc.

The worst thing about this type of documentation is that it clutters your code and makes the code hard to read. A class with 50 lines of code becomes 100 lines with comments. As a practice, try to remove all comments and see if it's easier to understand and read the class. I strongly believe it is. If not, it's a code smell and you should refactor your code! Comments should not be used to explain bad code.

When I talk to people about comments in code I often ask them two questions:

Do you think it's hard to maintain code?

How hard to you think it is to maintain comments?

If you change your code, do you also make sure to check if the comments are still correct after you've done the changes? Most people don't and you shouldn't really need to worry about it. Outdated comments can create confusion and bugs just because someone forgot to update them.

Monday, August 03, 2009 12:36:48 AM (W. Europe Daylight Time, UTC+02:00)
Sunday, July 19, 2009

At QCon London 2009, Dan Bergh Johnsson had a talk on the DDD track about how to make use of Value Objects (VO's) (The Power of Value - Power Use of Value Objects in Domain Driven Design (PDF)). In his talk he took a piece of code and refactored it into a better piece of code by using VO's. By doing this Dan showed some really good concepts of using VO's. Even though I knew about the concept of VO's before his talk, he made me realize many new scenarios where they are applicable. And more importantly that it is not limited to DDD.

So what is a VO anyway? Is it related to value type in .NET?

To answer the last question first: The real answer is no, but the way I see it there is a relation. A value type in .NET is everything that is not an object. Typically simple types like int, char, double, but also enums and structs. The relation is that often you find yourself creating VO's where value types was previously used. It is however not limited to value types.

Now to the first question. I first came across VO's after reading Evans DDD book (commonly known as the blue book). In DDD a Value Object is an object without an Id and are usually immutable. In examples of VO's, Address is commonly used, which I don't find particularly useful. I think Address way too often has an Id and people have a hard time relating to that as a Value Object. I find the Amount example I gave in an earlier post to a better example or the one below illustrated as an interface (borrowed from Dan):

public interface IPhoneNumber {
  bool IsValid {get;}
  string Number {get;}
  string AreaCode {get;}
}

How many times have you used the concept of a phone number in your code? Like mobile, fax, fixed etc… How often have you kept it as a string? How much code do you have for doing different types of validation, getting area code etc? Do you have it all in one place or scattered around in different places? Other examples are Money, ZipCode etc… These are great candidates for Value Objects.

Now that we know what Value Objects are, what is so powerful about them and why should I use them more? Great question :-) Below is my three reasons:

  1. Code readability - I find that using Value Objects greatly improve the overall code readability and eliminates comments. Just like good names on methods and properties does.
  2. DRY (Don't Repeat Yourself) - By having a Value Object for PhoneNumber, you avoid writing code to handle specific cases around phone numbers and you reuse them wherever the concept of a phone number is used.
  3. Helps people getting back into OO thinking – We who have been living in the Microsoft .NET world for a long time have been thought to think of programming from a data/database perspective and not object oriented programming as we once learned it. In other words: think of behavior instead of data.

When I started to use VO's, I soon discovered I used them all over. They really add great value to my code. As an example, lets implement the IPhoneNumber above:

public class PhoneNumber : IPhoneNumber
{
    private readonly string _phoneNumber;
    public PhoneNumber(string phoneNumber)
    {
        _phoneNumber = phoneNumber;
    }
    public bool IsValid
    {
        get { return Regex.IsMatch(_phoneNumber, @"^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$"); }
    }
    public string Number
    {
        get { return _phoneNumber; }
    }
    public string AreaCode
    {
        get
        {
            return Regex.Match(_phoneNumber, @"^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})").ToString();
        }
    }
}

The above code handles US phone numbers. To be used in a production system there should probably be even more validation in the regexp's, but I hope the example gives you and idea of what I'm thinking.

.Net | Architecture | CSharp | DDD | Patterns
Sunday, July 19, 2009 1:29:12 PM (W. Europe Daylight Time, UTC+02:00)

One of the code smells I see most often in C# and other OO languages is the misuse of switch/case statements. When I was a young Jedi (some might argue I still am :-)) I didn't see anything wrong with using the switch statement. Actually there still are a few cases where it's still applicable, but most usages I come across should have been solved differently. So why is this? What is so bad with the switch statement?

As Dan North tweeted me when I asked for the perfect refactoring solution for switch statements :-) :

A switch is often a sign of behaviour that should live elsewhere - so where should the code in the cases live?

Functions should only do one thing, the one thing which they state. Like CalculateInterest and ConvertDateToString should do exactly that; calculate interest and convert a date to string. Since switch always reside inside functions it almost always violates that principle.

Let's look at what Uncle Bob (Robert C. Martin) says in his Clean Code book about switch statements:

Even a switch statement with only two cases is larger than I'd like a single block or function to be. It's also hard to make a switch statement that does one thing. By their nature, switch statements always do N things.

My answer to Dan's question above was using polymorphism. The cases should live in their own classes. By doing that you don't have to modify existing code when introducing new behavior, you just create a new state (read class). Btw Dan is really good at asking questions to questions where you end up answering your own question :-)

Enough with the coding theory. Below is a method using a switch statement for getting messages from different systems. Typically these are systems that another system depends on (the system containing the below code). The messages might be if the system is available or not, or if there are any maintenance planned.

public string GetSystemMessage(System system)
{
    switch (system)
    {
        case System.System1:
            return GetSystem1Message();
        case System.System2:
            return GetSystem2Message();
        case System.System3:
            return GetSystem3Message();
        case System.System4:
            return GetSystem4Message();
        default:
            throw new ApplicationException("System not found");
    }
}

This is actually quite a good switch. It uses return instead of break and it only has one line per case. If you can't avoid writing a switch, this is how you should do it.

Now let's pull it apart and make it better and extendable. Time for refactoring.

Polymorphism by using Strategy Template Pattern
Here's my code using the Strategy pattern:

public interface ISystemStrategy
{
    string GetMessage();
}
public class System1Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System1";
    }
}
public class System2Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System2";
    }
}
public class System3Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System3";
    }
}
public class System4Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System4";
    }
}
public class SystemMessenger
{
    private readonly ISystemStrategy _system;
    public SystemMessenger(ISystemStrategy system)
    {
        _system = system;
    }
    public string GetMessage()
    {
        return _system.GetMessage();
    }
{
}

First I define an interface to be used by the different systems (ISystemStrategy) and next each system (1-4) implements that interface, resulting in a class for each case in the switch.In addition I have a class called SystemMessenger that is responsible for accessing the system and get a message.

The switch can now be replaced by this code:

public string GetSystemMessage(ISystemStrategy system)
{
    return new SystemMessenger(system).GetMessage();
}

Note that the "client" only relates to the SystemMessenger class and not to the different implementations of ISystemStrategy.

The benefit of this code might not be obvious. Actually it might give the impression that this was a lot of code for almost nothing. Well, don't be fooled. The strongest aspect of the above solution is that you don't have to change the GetSystemMessage later when/if a new system is added, you just implement a new class.

To prove the above, here's what I need to do to introduce a new system:

public class System5 : ISystemStrategy
    public string GetMessage()
    {
        return "System5";
    }
}

To use the new system, an instance of System5 will be sent into GetSystemMessage just as before, and SystemMessenger handles the rest as before. No code change!

Dictionary
Another refactoring option is using some type of lookup table. In my example I'll use a dictionary together with the Func<TResult> delegate. However, I don't recommend doing this unless you have a really good reason to do so. Stick with the Strategy pattern if you can.

public class SystemMessengerDictionary
{
    private readonly Dictionary<System, Func<string>> _systems;
    public SystemMessengerDictionary()
    {
        _systems = new Dictionary<System, Func<string>>
                           {
                               {System.System1, GetSystem1Message},
                               {System.System2, GetSystem2Message},
                               {System.System3, GetSystem3Message},
                               {System.System4, GetSystem4Message}
                           };
    }
    public string GetSystemMessage(System system)
    {
        return _systems[system]();
    }
    //GetSystemX Methods
    ...
}

I decided to show this example even if I don't like it. The reason is that it is better than the switch. The worst about this in my eyes is that the enum is still there. I just hate enums! When reading the code they look like classes with interesting behavior, but then you discover they're just glorified int's :-|

Conclusion
Hopefully this example will help you understand why switch is something you should avoid and also give you an example of how it should be done. But before you consider doing any refactoring of existing code, consider a second question Dan asked (answered?) me:

How would it evolve if you added a few more cases? And how likely are a few more cases?

This is an important question, because you don't want to refactor just for the sake of refactoring. Keep this in mind before making use of any of the suggested solutions above.

Sunday, July 19, 2009 12:53:15 AM (W. Europe Daylight Time, UTC+02:00)
Tuesday, April 28, 2009

image Is there anything more annoying than standing on a red light, when there is no car, motorcycle or carbon life form in sight? Maybe traffic lights elsewhere in the world are more intelligent, but at least where I live this happens from time to time. So what have this to do with developers? Good question, but let me first try to answer another one: Why do we have traffic lights?

From Wikipedia:

Traffic lights, also known as traffic signals, stop lights, traffic lamps, stop-and-go lights, robots or semaphore, are signaling devices positioned at road intersections, pedestrian crossings, and other locations to control competing flows of traffic.

I read: bla bla bla bla… control competing flows of traffic. I would probably have said something like this:

To avoid cars running into each other and avoid have people run over in a cross road. It’s a very logical way of saying stop or drive (red and green). Yellow is the same as green, but for taxis only. Traffic lights are regulated by sensors in the ground detecting where there is traffic and not + a algorithm to give green lights in a predefined order.

Now back to the first question, answered by asking a new one: What’s the equivalent of traffic lights in development? No, not red, green, refactor :-) I was thinking about frameworks, internal DSL’s and the like. Stuff that good developers create, which the not so good developers should use. To keep them from “hurting” themselves or the company they work for. Do you find that to be ok?

Tuesday, April 28, 2009 7:35:35 AM (W. Europe Daylight Time, UTC+02:00)
Saturday, April 04, 2009

Yesterday I published an interview I did with Chad Myers about FubuMVC on InfoQ. FubuMVC is a Model-View-Controller (MVC) implementation in ASP.NET. Much like ASP.NET MVC, but with some interesting differences. I encourage you to check it out!

Thanks to Chad and Jeremy D. Miller for agreeing to this and for giving great answers to my questions! And to Mark Nijhof for interesting discussions around MVC in general and Fubu in particular!

Saturday, April 04, 2009 9:03:03 PM (W. Europe Daylight Time, UTC+02:00)
Monday, March 30, 2009

This article is a translation of a Norwegian article I wrote earlier that got published on IT Pro a few days ago. It’s targeted towards IT decision makers and leaders, does not contain my usual technical focus, but should still be a valuable read for developers not familiar with Azure or want to know more about cloud computing.

Azure

Software and services developed by software providers today are primarily deployed on internal servers or made available through hosting providers. The “Cloud” opens a whole set of new possibilities, both functionally and financially. Several providers are shaping this new service and one of them is Microsoft with the Azure Services Platform (Azure).

This article will focus on what the “Cloud” has to offer software providers compared to today’s traditional services with focus on Azure specifically.

Scaling

Today it’s quite common, and almost acceptable, for websites to be temporary unavailable under extraordinary load. Examples can be ticket sales for popular concerts or some other event with limited time for registration. The load on the website is usually limited to a few hours, or even minutes, and the time is known in advance. What if you as a service provider could scale your services dynamically, to handle the increased traffic for that period? This is an example of what Azure has to offer.

Pay per use

Even though Microsoft have not officially revealed the details around the payment model for Azure, it’s natural to expect them to base their model on usage. Examples could be traffic in/out, storage, processing etc. Other providers, like Amazon and Google have similar models and it’s natural to believe that Microsoft will not deviate too much from these to be competitive.

Such a model will also be very attractive for startups. The cost of buying the necessary hardware, disk space, backup and broadband to run the website or service, not knowing how many will use it in advance, is often a good enough reason for not pursuing the opportunity. Taking advantage of a payment model like in Azure, the provider will have several advantages:

  • Small or no startup cost
  • Cost spread across time
  • Scaling on demand
  • Pay per use

    Microsoft’s biggest investment ever?

    clip_image001[4]There is a lot more behind Azure than software. To support such a scalable unit in the cloud a lot of investment in hardware, new technology and land areas is needed. One method Microsoft have used to build their datacenters, is to have preconfigured containers with server racks from HP and Dell, with built-in cooling and network. A lot of these containers are placed as close to a power plant as possible, where power is easily accessible, and when connected they are up and running in the cloud. All administration are then done remotely.

    If one, two or five servers in a container stop working, it will have no effect on data or traffic for the user of the cloud. Azure is designed so that servers can be pulled in and out of the cloud without affecting the service. This says a lot about the size and investment put in place for this to be a reality.

    Many datacenters are under construction several places in the world. One reason for Microsoft to build at several locations, and not just in the US, is to avoid the physical laws related to data transfers over the internet. Another important factor is the different regulations on different continents. As an example, some don’t want to have their data stored on servers in the US, in case the government demands to get access to their data. There is also difference in regulations in e.g. the US and Europe, that Microsoft needs to take into consideration.

    Built on known Microsoft products

    AzureArch

    Azure contains quite a few services as illustrated on the image on the left. Even though many of these services have new names, they are based on Microsoft’s existing products.

    Liver Services is a cloud service based on Windows Live, .NET Services on Microsoft .NET, SQL Services on SQL Server etc. These services are built on top of Windows Azure, which is a operating system specifically designed for running in the cloud. Windows Azure cannot be accessed as a regular operating system (through e.g. Remote Desktop), but developers can communicate with Windows Azure through a Application Programming Interface (API).

    Compared to Amazon’s cloud solution, where the user have direct access to the operating system (Linux or Windows), the user don’t have to worry about security or software updates, backups etc, since this is automatically managed by Microsoft.

    Security

    Security has been a central part of the development of Azure. The consequences of somebody getting unintentional access to services or data in the cloud would be catastrophically. Microsoft has built in many security mechanisms to avoid this. Some examples are data encryption, Code Access Security and backups to mention a few. It is expected that this is an area where users, developers, owners and Microsoft themselves will focus their efforts on in the time to come. Roy Ozzie, Chief Architect at Microsoft, says it’s extremely important for Microsoft to build trust in companies looking to invest in Azure as a possible solution, and that this is critical for the success of the cloud1.

    Microsoft have also made available a service they call .NET Access Control Service, that aims to support many of today's identity providers. By integrating the common identities that customers use or are common in a region (like a country or EU), this service can solve some of the identity issues we have today. Many are tired of having to create a new id every time they access a new website that has some type of identification, to display user specific information. What if the user could use only one, ore a handful identities, and choose which one to use towards a given website? By implementing .NET Access Control Service the user can do this and the web application can decide to trust it or not.

    Development tools with support for Azure

    Microsoft have made available a range of tools aimed for developers creating applications running on Azure. Already today developers can create and deploy application on Azure by using Visual Studio 2008 SP1, and develop in ASP.NET. The only requirement is for the developer to register in order to get access to the Azure services.

    In addition to the normal development tools, Microsoft has made it possible to develop and test on a local variant of the cloud on the developer’s computer. This will enable debugging of code during development and not have to deploy to the cloud every time a new functionality needs testing.

    When will Azure go live?

    Azure is available for developers today in Beta, so that they can already now try out the service and look at the potential possibilities. The service is however limited in this first Beta release, which makes it unattractive for production use. Steve Ballmer have stated that Azure will go live under Professional Developers Conference 2009 (PDC09) that is scheduled for 17th of November 20093.

    Conclusion

    With this new service, together with Microsoft and others investments in the technology, possibilities will arise that before was either very difficult or economically irresponsible to target. Examples where startups and smaller companies can bet big without enormous investments, where scaling opens up completely new possibilities and data processing taken to new heights, makes the cloud an attractive service for the future. It’s still too early to predict if this is going to be a success or not, but it’s clear in which direction the biggest providers are going.

    Sources:

    1Ozzie: Success of Azure comes down to trust - http://news.zdnet.co.uk/software/0,1000000121,39532953,00.htm

    2Introducting the Azure Services Platform by David Chappell - http://download.microsoft.com/download/e/4/3/e43bb484-3b52-4fa8-a9f9-ec60a32954bc/Azure_Services_Platform.pdf

    3Ballmer: Azure ready for release by end of year - http://www.infoworld.com/article/09/02/24/Ballmer_Azure_ready_for_release_by_end_of_year_1.html

    Monday, March 30, 2009 7:48:14 PM (W. Europe Daylight Time, UTC+02:00)
    Tuesday, March 24, 2009

    A couple of months ago I wrote an article about Azure Services Platform that just got published on ITPro. It's in Norwegian, but I plan to post it here in English as soon as I find some time to translate it.

    The article is targeted towards IT decision makers, meaning a lot of the technical details are missing. However, I still think it will be an interesting read for most techies as well.

    Tuesday, March 24, 2009 9:56:23 AM (W. Europe Standard Time, UTC+01:00)
    Saturday, February 07, 2009

    This interview kind of slipped my radar. Actually I didn’t have time until now to actually watch it. Now when I had however, I sincerely recommend everybody who’s slightly interested in DDD to watch it. It’s only 30 minutes.

    One of the more interesting things he talked about, was have the domain model care only about writes. This is something for my x co-workers at Contiki to have a look at (guys, I believe this could help you out). Why is this interesting and not only nuts!? Well, it opened up a door for me related to my concerns around the usage of DTO’s. Why would I want to transform all my domain objects to DTO’s for the sake of moving it to some client to display data on a screen?

    Greg suggest using DTO’s for displaying data to the user (think of it as a report), and pushing all your writes through your domain model (all changes to your domain). By doing this you get domain objects without getters and setters! That shouldn't be a goal in itself, but think about what it really means… Done thinking? Let me add a few more … (dots) Ok, ok… It means (as I interpret it) you create a separation between what your system needs to show to the end user and what your domain should care about. Why clutter the domain with reports?

    If you have any thoughts about this, please let me know. Thanks.

    Saturday, February 07, 2009 8:48:03 PM (W. Europe Standard Time, UTC+01:00)
    Friday, January 16, 2009

    InfoQLogo My article about The Future of Microsoft .NET Programming Languages just got published on InfoQ.This is my first attempt at being an editor for them, so if this works out I hope you will see more stuff from me in the near future.

    Would love to hear what you think, so drop me a comment if you like.

    Friday, January 16, 2009 2:56:53 PM (W. Europe Standard Time, UTC+01:00)
    Monday, December 15, 2008

    Last week I attended 2 sessions about the new Microsoft platform in the cloud: Microsoft Azure Services Platform. The first was held by David Chappell and the second by Clemens Vasters. Two great speakers. Unfortunately I didn’t get to see Clemens complete talk, because I had to catch a flight back home, but hopefully I got the main content of his talk.

    In this blog post I’m going to ask and answer some questions by the help of these two sessions + the additional study I’ve done around this topic.

    Disclaimer: The answers I provide below is based on my current knowledge of this platform and might not be correct now or in the future, though I’ve spent a fair amount of time making sure it is.

    What is it?

    It’s a platform where you can deploy and manage new services or even complete web applications into the “cloud”, in addition to make use of existing services already provided by the platform. This is often referred to as cloud computing. Today the Azure platform contains the following services: Windows Azure (the platform), Microsoft .Net Services, Microsoft SQL Services and Live Services. Microsoft SharePoint Services and Microsoft Dynamics CRM Services are also mentioned in relation to the platform. All of these services make up the Microsoft Azure Services Platform. By reading these names you may see the potential naming confusion? When you say Azure, do you mean Windows Azure or Azure Services Platform?

    Now you may ask, what is it really? From a simplified developers perspective it’s a platform on the internet (the cloud). Instead of hosting your web application/service on your local server, you publish it into the cloud. In addition it gives you access to the services you need to build a multi-tier architecture. From another perspective it’s big monster of a datacenter providing you with a lot of data power (virtual Win 2008 servers) to do your stuff, giving you the option to scale up and down at will or dynamically.

    How committed are Microsoft to this platform?

    As committed as they’ve never ever been before with anything as far as I can remember! They invest heavily in the technology and infrastructure needed to support this platform. By heavily I mean they’ve told the marked that this is such a huge investment that it will highly impact Microsoft’s money bin. As an example of this, here’s a short description of what they’re doing with their datacenters needed to host this beast:

    Every datacenter is set up of a grid of physical and virtual computers. These computers are delivered by HP and Dell and some in preconfigured shipping containers ready to be plugged in. I don’t mean the computers are ready to be plugged in, but the containers! What Microsoft then does is put a bunch of these containers close to a power plant (for obvious reasons), plug all the containers in and they’re up and running. At least that’s how it was described to me :-) The applications, services, data etc you have put into this cloud is distributed across many VM’s, meaning if a VM or server (hosting VM’s) goes down, it’s not a problem. There is always some VM on some server holding your data. Actually the shipping containers I mentioned are remotely managed and MS never enters any of these containers for maintenance. If a computer goes down and does not come up again, it just stays down. If this happens to a certain number of servers within one container, the whole container is disconnected from the grid and sent back to HP or Dell to be fixed, without affecting any of the applications or services! This little story told by Clemens Vasters really says a lot of the scale on this monster!

    Can I take my existing application and deploy it to the cloud using Azure Services Platform?

    The short answer is: no. The longer answer is: you might in the future. First of all the platform is still in Beta, but beside from that David Chappell says: “Azure Services Platform today targets the next Facebook”, meaning it’s highly scalable and can support a lot of users. To support this level of scalability there are some compromises to be made. On Azure this is (among other things) how you store and access data. Using a plain SQL server with relational tables and ADO.net would just not scale/perform. Thereby they decided to implement a different solution where the data are stored hierarchically and data is exposed via a RESTful interface using a LINQ like query language. Unless your application have this type of data implementation today, you would have to rewrite your data access and data layer. But don’t take my (or David’s) word for it, check out this video about table storage (which you would think is normal relational tables, but it’s not) from MS and you can make up your own mind: http://wm.microsoft.com/ms/msdn/azure/scalablestoragetables.wmv. Note though that in this video they’re using Windows Azure Storage and not SQL Services, but the same is true for SQL Services.

    If I can't deploy my existing app to Azure Services today, what CAN I do?

    The obvious thing is to wait and hope Microsoft will add support for relational tables allowing you to use existing SQL Server data implementations, but the Azure Services Platform is much more than a place to have your application and data. Your (local) application might want to interact with services in the cloud to enhance your existing application. I find the Service Bus to be especially interesting, or even the Access Control Service. This is only from my perspective and within the enterprise domain where I work. If you work with a more consumer oriented domain, you might find the Live Services interesting. Note that you don’t have to use the complete platform to make use of Azure Services. You can of course select the ones giving you value for you particular domain.

    What’s the difference between Microsoft SQL Services and Windows Azure Storage?

    First of all these two services looks very similar today and one might think why have both? My impression though is that Windows Azure Storage is going to remain much the same, but SQL Services are going to expand quite a bit (reporting, analytics, synchronization etc). Clemens offered this simplified analogy: “Think of Azure Storage as the registry on Windows, and think of SQL Services as your SQL Server.”. Another important difference is that Azure Storage is not built on existing SQL Server technology, but SQL Services is. Another interesting thing pointed out by David is that none of these services use SQL!? They use a RESTful interface with a LINQ like query language. He offered one explanation to this: SQL within MS means SQL Server :-)

    What’s the Access Control Service and is it limited to only Azure apps?

    The Access Control Service is “Microsoft’s humble attempt” to support as many access control providers as possible, so that this service will become a common place to perform identification. They state that “No one is willing to take this responsibility, so we have to” :-) Just think of it. How many providers of access control do we have today? Google, Microsoft, Amazon all have their own personal identity services on the internet. In addition there are a lot of others like Active Directory, Novell eDirectory, Apple Open Directory etc. What if this service would support the majority of these? Then you could use this service to do the access control for your system being in the cloud or not, and the end user could use his provider of choice. For more information about the Access Control Service check out the MSDN site: http://msdn.microsoft.com/en-gb/library/dd129876.aspx (note that this url might be quickly outdated).

    By choosing the Azure Services Platform, will I be locked in by that platform?

    By “locked in” I’m here going to assume you mean if you can move your cloud application away from this platform and on to another if you want to. Taking into account the current providers of cloud platforms we have today and the current services they provide, my impression is that you will be locked in. Just because of the simple fact that no one else is supporting .Net like Microsoft do. Hey, wait a minute… What if I use Amazon’s EC2 which gives me a Windows Server 2008 and a SQL Server, can’t I then move to that platform? That environment support .Net just fine. Well, it depends… :-) If you’re using the Azure Storage or SQL Services, you can’t cause it’s just not a plain SQL Server. It seams like the common thing to do among cloud services providers is to create their own data access solutions (or even programming languages like SaleForce.com have done), meaning you will be locked in on that. If you’re not using the data storage solutions you might not be.

    Why should I be afraid of being locked in anyway? I’ve already chosen Microsoft as my technology provider. Yea, but now you’re also locking onto your host. If your host (in this case MS) decides that the solution you’re running in their environment should be increased by a cost of 500% and you can’t afford that, what do you do? Find another cloud provider?

    However, one interesting thing to note about Azure Services Platform is what MS says about programming languages. They want (though they don’t do today) to support many other languages like Eclipse, Ruby, PHP and Python. Google only support Python, SalesForce only support their own language Apex, Amazon basically provide you with VM’s (Linux and Windows) leaving you to choose. Another interesting aspect is that MS seams to be very open about what and how they’re doing things. 

    People are talking about the Web Role and the Worker Role. What’s that all about?

    The Web Role and the Worker Role is part of the Windows Azure fabric (see separate section for more fabric info). Microsoft says:

    A web role is an ASP.NET web application that may be accessed via an HTTP or HTTPS endpoint. Web roles run in integrated pipeline mode on a hosted IIS7 web core. 
    ..and/or:
    A web role is a web application accessible via an HTTP and/or an HTTPS endpoint. A web role is hosted in an environment designed to support a subset of ASP.NET and Windows Communication Foundation technologies.

    A worker role is a background processing component. It does not accept inbound network connections.
    ..and/or:
    A worker role is a background processing application. A worker role may communicate with storage services and with other Internet-based services. It does not expose any external endpoints. A worker role can read requests from a queue defined in the Queue storage service.

    A service may consist of a single web role, a single worker role, or one of each.

    When you create Azure projects in Visual Studio, you select which Role you want your project to be (or both). As described above the main difference between the two is that the web role allow incoming traffic, while the the worker role does not.

    What’s “The Fabric”?

    The Fabric, or more accurately Windows Azure fabric, is the operating system that the services run on. Again from MS:

    The Windows Azure fabric offers an Internet-scale hosting environment built on geographically distributed data centers. This hosting environment provides a runtime execution environment for managed code. The fabric handles load balancing and resource management and automatically manages the life cycle of a service based on requirements established by the owner of the service. The developer includes with the service code specifications for the service topology, the number of instances to deploy, and any configuration settings. The fabric deploys the service and manages upgrades and failures to maintain availability.

    To try to simplify (in my words): Below the fabric you’ll find a lot of VM’s. On top of the fabric you’ll find Compute and Storage. The fabric host .Net and take care of networking stuff.

    What if I’m not going to build “The next FaceBook”, is this still something for me?

    Absolutely. Even though the architecture behind it all is built so that it can handle the next Facebook, it does not mean you can’t use it for an enterprise solution which have less than 1000 users or an application you want to share with your friends. It will be interesting though to see if MS will provide us with different data models, so that we don’t have to use a really scalable one, when we will never need it, also allowing us to port existing solutions onto their platform.

    What’s it going to cost?

    No one knows. At least not outside of Microsoft. We do however know some thoughts they have around the pricing model(s). It does not look like they’re going for a “simple” price model as e.g. Amazon which charge per hour. They will probably use a combination of CPU, network, storage and transactions(data) to calculate the price. More details can be found here: http://www.microsoft.com/azure/pricing.mspx (note that this url might quickly become outdated).

    Who else out there offer cloud services?

    According to David Chappell; Amazon, Google and SalesForce.com are the leading providers today. All of these provide different solutions and pricing models.

    Will everybody now deploy their apps to the cloud?

    Not now, but I defiantly see this as a very attractive hosting model in the future, and for some it is already today with services provided by e.g. Amazon. I would think it’s especially interesting for startups that does not have the resources (money and knowledge) to set up a datacenter for hosting their solution.

    Hi, this is your mom. Do I need to know what this is?

    No. You together with the rest of the world not running an IT company or doing programming can happily not care and just use whatever services that will be provided through this platform without you knowing. Btw mom, you don’t have to read my blog if you don’t want to ;-)

    Where’s Hello Cloud?

    It’s here: http://wm.microsoft.com/ms/msdn/azure/hellocloud.wmv
    ..and implemented here: http://hellocloud.cloudapp.net/

    Are any of the material from the sessions you attended made available for the public?

    You can find David Chappell’s presentation here: https://cid-88b5769d9bbdf846.skydrive.live.com/self.aspx/Offentlig/Azure%20Services%20Platform--Chappell.pdf

    Monday, December 15, 2008 12:50:37 AM (W. Europe Standard Time, UTC+01:00)
    Tuesday, November 25, 2008

    On the DDD mailing list a few days ago Richard Pawson posted that he and his team have created a DDD framework for .Net. Since I’ve had my head down in DDD for the last couple of months I thought I’d check it out. When posting this I’ve still not tried it, but I’ve watched some of the videos which you can find here:  http://www.nakedobjects.net/demo/demo_intro.shtml

    Honestly I’m not sure what I think of DDD frameworks in general. By definition I’m skeptical :-), but I promise to try it out and come back with some sort of conclusion of my findings and impressions. Btw. I’ve not been approached by Naked Objects to review their product in case you were wondering :)

    .Net | Architecture | DDD | Patterns | Software | Tools
    Tuesday, November 25, 2008 8:44:41 AM (W. Europe Standard Time, UTC+01:00)
    Saturday, September 27, 2008

    Børge Hansen is the latest employee of the DPE team at Microsoft Norway. The DPE team is responsible for MSDN Live, the Norwegian MSDN site, follow up on MS related community activities, Norwegian Developers Conference and are the technical advisors from MS for Norwegian companies. If you're a developer this is the guys you should get in contact with to get closer to Microsoft and find out what they can do for you.

    Anyway, Børge is DPE's Architect Advisor. I've met him a couple of times and already had some interesting discussions. We're currently discussing if there is something we can do in the community (like NNUG) to spread the word about architecture and what it means to be an architect. Hopefully something great will come out of this and we as architects (or coming architects) will have a architecture community to throw ideas and discussions at. One of the things I vision is that architecture is less platform dependant, so there should be room for more than just MS technologies in this community.

    Saturday, September 27, 2008 11:25:13 PM (W. Europe Daylight Time, UTC+02:00)
    RSS RSS - Comments Twitter LinkedIn
             
    SEARCH
     
     
             
    TOP POSTS
       
             
    NAVIGATION
       
             
    CATEGORIES
      .Net (57) Agile (29) Ajax (5) Architecture (17) Articles (1) ASP.NET (3) ASP.NET-MVC (1) Blogging (12) Books (2) BPEL (1) CleanCode (1) CloudComputing (7) Community (2) CSharp (11) DasBlog (5) Database (2) DDD (5) Deployment (14) DSL (1) Events (37) ExtremeProgramming (6) Fun (6) Gadgets (4) IIS (8) InfoQ (4) Java (2) Lean (2) Linq (2) MemoryLeaks (5) Microsoft (37) MVC (1) NDC (2) NNUG (35) Other (10) Patterns (9) Performance (3) Scrum (17) Security (3) Silverlight (4) Software (19) TeamManagement (11) TechEd (7) Testing (4) Tools (23) TvGuide (1) Vista (15) VisualStudio (16) WCF (7) Web (15) Windows (10) WiX (9) Work (16) Workflow (3)  
             
    ARCHIVE
       
             
    BLOGROLL
       
             
    ON THIS PAGE...
     
    Using IIS7 And Application Request Routing as Load Balancer – Part 2
    Using IIS7 And Application Request Routing as Load Balancer – Part 1
    Presenting Windows Identity Foundation At MSDN Live In April
    QCon London Early Bird About To Expire
    Are SharePoint Developers Unable To Be Real Craftsmen?
    Replace Comments With Code
    Start Using More Value Objects!
    Different Ways of Refactoring Switch/Case
    Developers and Traffic Lights
    InfoQ: Interview With Chad Myers on FubuMVC
    Article: Microsoft Azure - A new era for software companies?
    Azure Article on ITPro
    Greg Young on DDD
    The Future of Microsoft .NET Programming Languages
    Microsoft Azure Services Platform
    Naked Objects - DDD framework for .Net
    Architecture community in Norway