Monday, 10 November 2008

Day 1 - 16:00 : The future of composite applications and SOA - everything they told you and why it isn't true (SOA202)

The presentation opened with a video about the history of models. You can view this light hearted video here: www.modelsremixed.com

Presented by Mark Berman and Steven Martin, this session covered (in quite simple terms) the future of SOA and some misnoma's about SOA in general. To begin with they addressed the following mistakes;

SOA is a product?
Service oriented architecture is not a what, it's a how. You don't go and buy Microsoft SOA or IBM SOA, you build applications using the principles of SOA. It's another way to build applications or even another way to re-purpose them. In fact most recent high ROI implementations of SOA haven't been green field developments, but instead have been a wrapper over existing software, exposed as SOA.

SOA aligns business to IT
No, this is what people do. No technology can align business to IT, only people can achieve this.

SOA governance fixes everything
This is wrong, SOA governance alone is not enough - governance needs to span all of IT, not just SOA.

SOA stops at the firewall
Notice in many organisations today how the administrator of the firewall holds immense power! To truly benefit from SOA we need to be thinking of SOA as starting at the firewall.

The presenters followed this up with a claim that essentially Microsoft pioneered SOA. This is claimed as Microsoft, along with other constituents, pioneered web services, a fundamental part of SOA itself.

One of the issues Microsoft are looking to address is how, it's perceived at least, only blue chip / fortune 500 / FTSE companies are able afford to implement SOA successfully. They wish to make it available for the smaller organisation too.

Dublin is the codename for a set of extensions to the windows server platform (IIS7 specifically) that are the next evolution of the WAS/IIS platform that will be used to host, run and manage windows communication foundation and windows workflow foundation applications.

Released after visual studio 2010, dublin will provide facilities to manage, throttle and inspect individual services within a deployed application. Combined with OSLO, the graphical modelling toolset and DSL environment, building, deploying and managing services is purported to become easier than it is at present.

Whilst this session was titled the future of composite applications and SOA, there wasn't enough depth to take away anything about the future of SOA beyond the rough idea of what dublin will be.

Day 1 : The Keynote

After introductory comments and reinforcement of the Azure message, Jason Zander, general manager of visual studio team developer division of Microsoft took to the stage to present the future of visual studio in the guise of visual studio 2010. It got off to a flying start as VS crashed within a few minutes of the demo - but lets face it this IS pre-alpha software, so is easily forgiven.

Amid many new enhancements in vs.net 2010, there were key improvements discussed in the following areas;

  • Understanding the code
  • Building web applications
  • Creating office business applications
  • Using the power of C++

There was quite a lot of depth to some of these changes, but to summarise some of what I felt were the more important ones;

A new "architecture explorer", is being introduced to help you visualise the structure and dependencies within your solution. It visually displays the relationships between assemblies within a project and provides drill down into the assemblies to see relationships between individual classes and namespaces and the connections between them are weighted according to the level of dependency.

In addition to visualising the dependencies between areas of your solutions, individual portions of code can be extrapolated into UML 2.1.1 sequence diagrams - which is a useful addition, and I'm hoping this eludes to visual studio 2010 ultimately supporting UML modelling out of the box.

Testing was a major focus for the next release, with 2010 introducing the testing activity centre, code-named Comono(?). This is a test environment for managing and running manual scripted tests. This is a major boon for the end-to-end experience and integrates into new debugging facilities in visual studio and TFS. Some of the highlights for this new facility;

  • Testers are presented with scripted steps to follow - test steps are marked as passing or failing.
  • During testing, the system is able to take video of what the tester is doing as part of their session and also record replay information about the state of the application that can be replayed in the debugger within visual studio.
  • When failures occur, a bug can be entered directly into TFS, attaching any video or replay session.
  • In TFS, viewing any raised bugs from this process shows a list of steps the tester took, and each step provides a hyperlink to the timecode within the video so you can see exactly what the tester was doing.
  • Historical debugging of the testers snapshot allows debugging of the testers session.
  • The aim and objective of this suite is to eliminate the "unable to reproduce" responses developers often run into and to bring manual testing into the managed process.

Alongside this new manual test studio, is the test lab management facilities. This allows virtual test environments (eg; different servers for various tiers) to be provisioned and used within the test. Again this is integrated back to TFS and visual studio, allowing virtual machines to be restored into the state they were at the point a bug was raised.

Within visual studio, the editor itself has had a complete WPF overhaul. As a result of this, the editor can take advantage of lots of WPF goodness like the ability to contain and display any form of information, from the source code we know and love, to diagrams, graphics and other glyphs that might help us to understand or navigate the code more efficiently. The editor uses the extensibility framework (MEF) allowing for multiple add-ins for the editor and add-ins on add-ins on add-ins. X-copy deployment of extensions will also be supported as a by-product.

The editor provides for intellisense support for jQuery and also offers a bunch of new refactoring capabilities - which I can't help but think treads on the toes of Resharper, which has got to annoy JetBrains somewhat.

A new configuration transformer toolset is provided, which allows you to define transformation rules that will be applied when an application (web in this case) is deployed to various environments. Eg: Ability to change connection strings when preparing for production deployment versus debug deployment etc. One touch publishing of websites is also a new facility, where your entire web application is built and zipped into a single file ready for deployment with msdeploy.

In the sharepoint space, demonstrations were given on the new sharepoint server explorer extensions and the WSP importer, which looks like it should speed up sharepoint development no end, especially tied to the new packaging explorer which allows you to package and deploy sharepoint applications easily.

Finally, Jason demonstrated several new features of C++ including running parallel for loops and such like for performance.

Saturday, 1 November 2008

Datasets - what's the problem?

I was talking with a friend of mine last night, an experienced developer who's leading a team of guys building a large commercial enterprise application. We were just chewing the fat over data access and how we approach things differently - I'm a fan of the domain model and use OR/M for persistence - usually NHibernate, but my buddy was advocating the use of the Dataset.

Many of us are told that the Dataset is just evil incarnate, but that's not actually true - the Dataset does serve a purpose, just not one in an enterprise application with complex domain logic.

The issue with a dataset is that it's not representational of data, it merely contains it. Beyond the activity of querying data and performing straight forward operations, it requires additional components. Representing complex logic and interrelated business entities is harder than it needs to be.

A domain driven approach on the other hand, with entities representing data, provides more flexibility to describe your logic - for instance, a customer object will contain properties to represent itself, along with business logic for operations and rules that govern a customer object and it's relationships to other objects.

Does that mean that the DataSet is intrinsically evil? No!

Sure dataset's have their problems - amongst others, they enforce a database centric view of data and when they serialise they also serialise a description of the schema of the data resulting in a bloated payload (this can be disabled). Despite these problems however, for trivial systems, they can serve a purpose.

It's a matter of choice. Even for trivial applications I would advocate a domain approach, but that's my preference. For anything non-trivial however and for any enterprise system, I'd avoid the dataset.

Friday, 31 October 2008

Microsoft kill off LINQ to SQL

http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx

Microsoft are dropping support for LINQ to SQL as of .NET 4.0. This is a kick in the face for anyone who has invested time in what is a reasonable, if very basic, ORM solution - get porting folks!

I'm just glad I chose to continue using NHibernate.

Tuesday, 28 October 2008

ASP.NET error: could not load file or assembly App_Web*

Reminder for me more than anything....

Useful information about this annoying error:
http://yetanotherdeveloper.com/post/2008/08/10/Could-not-load-file-or-assembly-App_Web.aspx

Summary of options:

  • Turn off batch compilation in web.config (<compilation batch="false"..)
  • Clear down the contents of Temporary ASP.NET Files (in windows\Microsoft.NET\Framework\vX.xx\)

Monday, 27 October 2008

Silverlight and Cross domain services

Silverlight 2 allows you to invoke a web service on a different domain to where your XAP came from. In order to do this however, the owner of the service needs to enable it to allow cross domain calls.

This entails creating an xml file in the root of the service web server called clientaccesspolicy.xml. A skeleton of this file, allowing any caller from any domain, is shown below;

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*" />
      </allow-from>
      <grant-to>
        <resource include-subpaths="true" path="/" />
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

Friday, 15 August 2008

Exposing new properties for control templates using attached properties

There are many instances where you want to write a groovy looking control template to apply to your WPF controls only to find that the control you want to template falls short in the properties it provides - eg: Try specifying the over state gradient brush for a button using only it's exposed properties. In these situations you need some custom properties on the control to be able to tell your template what to do.

In this situation there are several options open to you - you could hijack a property - bad idea when it comes to maintainability. Alternatively you could inherit the control and introduce the new properties - again, not the most ideal situation under WPF's composition model.

By far the most flexible and easiest way to achieve this behaviour is with attached dependency properties.

In the following example, we want to extend all of our buttons to provide not just a single line of text as you'd find on normal buttons, but we also want to have customisable sub-title line. To achieve this we start with the custom dependency property;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ButtonPropertyExtender : DependencyObject
{
  public static readonly DependencyProperty SubTextProperty =
    DependencyProperty.RegisterAttached("SubText",
      typeof(String), typeof(ButtonPropertyExtender),
      new FrameworkPropertyMetadata(null,
        FrameworkPropertyMetadataOptions.AffectsMeasure |
        FrameworkPropertyMetadataOptions.AffectsArrange));

  public static void SetSubText(UIElement element, object o)
  {
    element.SetValue(SubTextProperty, o);
  }

  public static string GetSubText(UIElement element)
  {
    return (string)element.GetValue(SubTextProperty);
  }
}


Quite simply this registers a custom attached property with WPF and allows it to be attached to any element. The next thing we do is use the new property on our button thus;

1
<Button xc:ButtonPropertyExtender.SubText="Subtitle text">
Click Me!
</
Button>

And finally, to use our new property in the control template, we bind to it - notice however how we cannot use the {TemplateBinding} shortcut - instead we must use the full binding expression to get to the new custom property.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<ControlTemplate TargetType="Button">
  <Border Background="{TemplateBinding Background}"
      BorderBrush="Black"
      BorderThickness="2"
      CornerRadius="10" >

    <StackPanel HorizontalAlignment="Center">
      <ContentPresenter Content="{TemplateBinding Content}"/>
      <TextBlock
        Text="{Binding
RelativeSource={RelativeSource TemplatedParent},
         Path=(xc:ButtonPropertyExtender.SubText)}"
/>
    </StackPanel>
  </Border>
</ControlTemplate>

Wednesday, 2 July 2008

Database Schema and Source Control - the tools

A couple of weeks ago I said I would release some example source code for managing database change and getting schemas into source control painlessly. Attached is the full source to the tool used in this approach. It's by no means production quality, I literally knocked this up in a couple of hours this evening, but it works and should provide a basis for improvement.

The tool allows you to follow the approach discussed in my earlier post and have your scripts applied to your database as needed. The tool will also generate database creation and update scripts instead of applying them to your database directly - which is handy for packaging releases.

You'll find 3 projects in the solution - an example database project to run the tools against, a command line implementation of the schema tool and the schema engine itself.

To use the command line tool, use the following arguments;

Deepcode.SchemaTool.Cmd.exe - followed by; (items in red are mandatory);

-h Display usage information
-l [location] The location of your database project
-m [dbscript] Specify db to run in database update mode - scripts will be applied to the database specified. Specify script to generate scripts to create the entire database and to patch it.

When running in database update mode (-m db), use these additional arguments;

-s [server] The SQL Server to target (default to (local))
-d [database] The database to target
-id [databaseid] The id of the database in the DatabaseVersions tracking table.
-c If present, instructs the engine to create the database if it doesn't exist.
-cd If present, instructs the engine to create the database. If it exists already, it will first be dropped.
-u [username] The SQL username to login to the server as - if not present the system will use windows authentication as the current windows identity.
-p [password] The password to connect to SQL server, when -u is being specified

When running in script generation mode (-m script), use these arguments;

-o [location] The location to store the generated SQL scripts.

To use this as part of your development process, place a copy of the exe into your trunk/library directory (or whatever strategy you use for SCC of dependencies), and create two batch files - one to update the database and one to generate the scripts. Then, whenever you make a change, just run the update script. When you release a version, run the generation script.

I didn't have time to do it tonight, but it should be trivial to wrap the same functionality as the command line host into a custom MsBuild task and automate everything. If anyone does this, please post a link to your wrapper source.

And finally, again, remember this isn't production quality, I offer no warranty etc...use at your own risk.

Click here for the source code

Thursday, 19 June 2008

Database schema in source control

Getting your database schema under source control is an important part of any development process as your solution isn't just the finely crafted code you've built, it's also the database schemas it uses.

There are a variety of ways of bringing your schema into SCC, such as using Visual Studio Database Professional Edition, or one of the fine offerings from red gate, at an absolute minimum you should keep a script that is capable of recreating your schema, but with a little planning and a simple custom tool, it's reasonably straight forward to manage your schema very well without spending a fortune on tools. I present below the mechanism I'm using for the next release of flux. If you've not yet got your database schemas under source control, I'd recommend doing it now!

The way I approach database schemas in source control is to setup a project with the following directories (if using visual studio, you can setup a simple database project and then create the structure shown below).

image

The concept is, we define an immutable baseline that represents the initial structure of our database tables that, once committed to source control, will not be changed. We then apply any version updates to the structure to update it to the latest version before finally dropping and re-creating any dynamic elements such as stored procedures, views and functions.

The baseline directory contains a single script to establish the initial structure of the database. At an absolute minimum this establishes a DatabaseVersions table as below and inserts a record into it that states the current version is 1.0.0.

image

Note that the baseline scripts should not include the creation of any stored procedures, views, functions or other dynamic elements - these are re-created each time we run the update process against our database.

With the baseline in place, the updates directory is then used to apply change scripts to the database as each change is made. Each change script makes all of the adjustments necessary in one atomic unit. Again updates are only to the tables, keys and constraints and not the dynamic elements which are covered shortly. As each update is applied, it sets the version number in the DatabaseVersions table to the new version.

Each update is made up of one single script, and the file is named according to the version of the database that it updates. eg: If your script will update a version 2.0.4 database to 3.0.0, the script will be named update020004.sql.

*** EDIT: BE AWARE, YOUR UPDATE SCRIPT SHOULD RUN WITHIN ONE BIG SQL TRANSACTION AND ROLLBACK ALL IF ANYTHING FAILS – THIS WILL ENSURE YOUR UPDATES AREN’T PART COMMITTED ***

The dynamic directory contains all of the various scripts that will drop and re-create any views, stored procedures, functions etc. Each object is represented by it's own script and each script should start by querying if the object already exists before dropping it and re-creating.

The dynamic elements allow the database schema to be validated - for example, if a view uses a field that has been dropped in a recent update, the update process will fail as the view cannot be re-created with this erroneous field.

As a manual process this would all be reasonably tiresome, so I suggest the creation of a custom build task, or command line application that you can run against a database, it's objectives being;

  1. Connect to the database (optionally create it)
  2. Does the DatabaseVersions table exist? If not, run the initial baseline script against the database.
  3. Read the current version number from DatabaseVersions.
  4. If a script exists named updateXXYYZZ.sql in the Updates directory, run it and then repeat from step 3.
  5. Execute every script contained in the dynamic directory.

All of the above would be completed within one transaction, so if any part of an update failed, the entire update phase would fail.

Having this process in place allows you to keep your schema as safe as you keep your code, but also keeps the overhead of maintaining it reasonably low.

You can even use the above process during the initial development of your baseline. Your baseline starts out as being nothing more than the creation of the database version table, with each update then adding the tables as you develop them. Once your happy with your database and want to make it the new baseline, simply re-script it's structure, overwrite the current baseline and remove the update scripts.

Your tool to process the scripts should also be capable of generating standalone update scripts that can be shipped with your application. Your app will need a script to create the initial release 1 database, but will also then need a single "update v1 to v2" script, followed by an "update v2 to v3" script and so on. This should be achieved by running the tool in script generation mode. It would then;

1. Spit out a script to create the entire database in it's present version. Incorporating baseline, all updates and all dynamic items.

2. Spit out a script to move from baseline to v2, v2 to v3 and so on - but without the dynamic components. Along with a separate script to update the dynamic components.

This would mean that the user of your app only needs to run the main script if they are installing a new instance, or run the individual update scripts followed by the single dynamic script to update an existing instance.

[Edit: The source code to a tool that implements all of the above is now available from this post or from codeplex here]

Wednesday, 27 February 2008

Beware DTC configuration in a cluster

Suffered from a severe amount of head scratching today due to using Mutual Authentication in Microsoft DTC.

On a particular project of a clients, we have a bunch of applications and a bunch of services. These services use System.Transactions and nest a bunch of transactions together in a DAO layer - which all use the transaction scope option of required, so if a transaction's already started, it simply enlists in it.

Everything appeared to work fine - the clients were working, the services on the test server were working fine, connecting to our database cluster and everything seemed happy and ready for a dry run test into the live environment. When we moved the services into a cluster however, everything failed - with the ubiquitous "communication with the underlying transaction manager failed" error, so common when DTC isn't configured correctly.

After two days, the operations guys discovered (with a little help from Microsoft support) that the issue was actually because we were using mutual authentication configuration in MSDTC.

Mutual authentication works fine server to server and in all non-clustered environments, but where you have a cluster that needs to talk out to another server, or two clusters talking to each other, mutual authentication is a very bad thing, and armed with the knowledge of why, it's easy to understand in hindsight.

It boils down to how mutual authentication works. Normally, the mutual authentication conversation between two machines might go like this;

Machine A: "Hi, I'm Machine A, with IP address 192.168.01"
Machine B: "Are you really Machine A, with IP address 192.168.0.1"
Machine A: "Yeah!"
Machine B: "Cool"

And everything is happy, however, assuming we have two clusters as follows;

  • Cluster A (Database cluster - virtual IP 192.168.0.1)
    • Server A.1 (IP 192.168.0.100)
    • Server A.2 (IP 192.168.0.101)
  • Cluster B (Services cluster - virtual IP 192.168.0.2)
    • Server B.1 (IP 192.168.0.102)
    • Server B.2 (IP 192.168.0.103)

The conversation goes like this:

Cluster A: "Hi, I'm Cluster A, with IP address 192.168.0.1"
Cluster B: "Are you really Cluster A, with IP address 192.168.0.1"
Server A.1: "No, I'm actually Server A.1 with IP address 192.168.0.100"
Cluster B: "Then I suggest you leave before I call the boys in!"

Clustered servers don't confirm their identity as the cluster virtual name/ip, and instead validate as the current active node in the cluster. This makes mutual authentication fail.

So the moral of the story - if you're using clusters, you simply cannot use mutual authentication. It does actually say this in the recommended cluster configuration, but it's not very clear - is says "You cannot select mutual authentication" - with no explaination, which makes it sound like it's disabled, so when you realise it's not and it's available, you can easily and naturally turn it on thinking that would be the most secure configuration.

As a final note - we were told that in internal networks, the use of "No authentication" is actually recommended practice and that you don't need to use the higher authentication levels.