Introduction to SOLID – DDDSW 2014

Slide Deck

The slide deck is available for download in PDF format.

SQL Injection Attacks – DunDDD 2012

Examples

The examples were run against a copy of the Adventure Works database.

Required Tables

For the Second Order Demo you need the following table added to the Adventure Works database:

CREATE TABLE [dbo].[FavouriteSearch](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [nvarchar](128) NOT NULL,
	[searchTerm] [nvarchar](1024) NOT NULL
) ON [PRIMARY]

GO

Slide Deck

The slide deck is available for download in PDF format.

Further Reading

During the talk I mentioned a lesson from history on why firewalls are not enough.

I also showed XKCD’s famous “Bobby Tables” cartoon, and also a link to further information on dynamic SQL in Stored Procedures.

More information about the badly displayed error messages can be found amongst two blog posts: What not to develop, and a follow up some months later.

I wrote a fuller article on SQL Injection Attacks that you can read here although it is a few years old now, it is still relevant given that SQL Injection Attacks remain at the top of the OWASP list of vulnerabilities.

Aberdeen Developers – Introduction to Parallelisation

Examples

Here are all the examples from Thursday evening’s introductory talk on Parallelisation at the Aberdeen Developers User Group.

Slide Deck

You can download the slide deck here.

DDD Belfast Parallelisation Talk

Examples

Here are all the examples from Saturday’s introductory talk on Parallelisation at DDD Belfast.

Slide Deck

You can download the slide deck here.

SQL Server User Group: SQL Injection Attacks

Examples

The examples were run against a copy of the Adventure Works database.

Required Tables

For the Second Order Demo you need the following table added to the Adventure Works database:

CREATE TABLE [dbo].[FavouriteSearch](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [nvarchar](128) NOT NULL,
	[searchTerm] [nvarchar](1024) NOT NULL
) ON [PRIMARY]

GO

Stored Procedure with dynamic SQL

This is the stored procedure from the last demo which shows the Stored Procedure dynamically building a SQL statement that is susceptible to a SQL Injection Attack.

CREATE procedure [dbo].[SearchProducts]
(
  @searchId int
)
AS
BEGIN

  DECLARE @searchTerm NVARCHAR(1024)
  SELECT @searchTerm = searchTerm FROM FavouriteSearch WHERE id = @searchId

  DECLARE @sql NVARCHAR(2000) =
  'SELECT ProductID, Name, ProductNumber, ListPrice
  FROM Production.Product
  WHERE DiscontinuedDate IS NULL
  AND ListPrice > 0.0
  AND Name LIKE ''%'+@searchTerm+'%''';

  EXEC (@sql);

END

 

Slide Deck

The slide deck is available for download.

Further Reading

During the talk I mentioned this lesson from history (why firewalls are not enough), I also showed XKCD’s famous “Bobby Tables” cartoon, and also a link to further information on dynamic SQL in Stored Procedures. More information about the badly displayed error messages can be found amongst two blog posts: What not to develop, and a follow up some months later.

I wrote an article on SQL Injection Attacks that you can read here.

DDD South West Parallelisation Talk Overview

Examples

Here are all the examples from Saturday’s introductory talk on Parallelisation at DDD South West 2011.

Slide Deck

The slide deck is also available as a PDF file (15.9 Mb)

Parallelisation Talk examples – Cancelling Tasks

This example showed what happens when tasks are cancelled. In this example, some tasks will be able to run to completion, others will be cancelled and other won’t even get a chance to start because the cancellation token was signalled before the task gets a chance to start.

Here is the code for the cancellation example shown in the talk

class Program
{
    static void Main(string[] args)
    {
        const int numTasks = 9;

        // Set up the cancellation source and get the token.
        CancellationTokenSource tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;

        // Set up the tasks
        Task[] tasks = new Task[numTasks];
        for (int i = 0; i < numTasks; i++)
            tasks[i] = Task.Factory.StartNew(() => PerformTask(token), token);

        // Now the tasks are all set up, show the state.
        // Most will be WaitingToRun, some will be Running
        foreach (Task t in tasks.OrderBy(t => t.Id))
            Console.WriteLine("Tasks {0} state: {1}", t.Id, t.Status);

        // Give some of the tasks a chance to do something.
        Thread.Sleep(1500);

        // Cancel the tasks
        Console.WriteLine("Cancelling tasks");
        tokenSource.Cancel();
        Console.WriteLine("Cancellation Signalled");

        try
        {
            // Wait for the tasks to cancel if they've not already completed
            Task.WaitAll(tasks);
        }
        catch (AggregateException aex)
        {
            aex.Handle(ex =>
            {
                // Handle the cancelled tasks
                TaskCanceledException tcex = ex as TaskCanceledException;
                if (tcex != null)
                {
                    Console.WriteLine("Handling cancellation of task {0}", tcex.Task.Id);
                    return true;
                }

                // Not handling any other types of exception.
                return false;
            });
        }

        // Show the state of each of the tasks.
        // Some will be RanToCompletion, others will be Cancelled.
        foreach(Task t in tasks.OrderBy(t => t.Id))
            Console.WriteLine("Tasks {0} state: {1}", t.Id, t.Status);


        Console.WriteLine("Program End");
        Console.ReadLine();
    }

    static void PerformTask(CancellationToken token)
    {
        try
        {
            // The loop simulates work that can be cooperatively cancelled.
            Console.WriteLine("Task {0}: Starting", Task.CurrentId);
            for (int i = 0; i < 4; i++)
            {
                // Check for the cancellation to be signalled
                token.ThrowIfCancellationRequested();

                // Write out a little bit showing the progress of the task
                Console.WriteLine("Task {0}: {1}/4 In progress", Task.CurrentId, i + 1);
                Thread.Sleep(500); // Simulate doing some work
            }
            // By getting here the task will RunToCompletion even if the
            // token has been signalled.
            Console.WriteLine("Task {0}: Finished", Task.CurrentId);
        }
        catch (OperationCanceledException)
        {
            // Any clean up code goes here.
            Console.WriteLine("Task {0}: Cancelling", Task.CurrentId);
            throw; // To ensure that the calling code knows the task was cancelled.
        }
        catch(Exception)
        {
            // Clean up other stuff
            throw; // If the calling code also needs to know.
        }
    }
}

 

Here is the output of the program (your results may vary):

Task 1: Starting
Task 1: 1/4 In progress
Task 2: Starting
Task 2: 1/4 In progress
Tasks 1 state: Running
Task 3: Starting
Task 3: 1/4 In progress
Tasks 2 state: Running
Task 4: Starting
Task 4: 1/4 In progress
Tasks 3 state: Running
Tasks 4 state: Running
Tasks 5 state: WaitingToRun
Tasks 6 state: WaitingToRun
Tasks 7 state: WaitingToRun
Tasks 8 state: WaitingToRun
Tasks 9 state: WaitingToRun
Task 1: 2/4 In progress
Task 2: 2/4 In progress
Task 3: 2/4 In progress
Task 4: 2/4 In progress
Task 1: 3/4 In progress
Task 2: 3/4 In progress
Task 4: 3/4 In progress
Task 3: 3/4 In progress
Task 1: 4/4 In progress
Task 2: 4/4 In progress
Task 4: 4/4 In progress
Task 3: 4/4 In progress
Task 5: Starting
Task 5: 1/4 In progress

To this point the tasks have been given a chance to operate normally. The tasks that have started are outputing to the console their progress. The main thread reports on the state of the tasks and shows tasks 1 to 4 are Running while the remainder are WaitingToRun. After a while the scheduler decides to start task 5.

Next the tasks are going to be cancelled.

Cancelling tasks
Cancellation Signalled
Task 1: Finished
Task 2: Finished
Task 4: Finished
Task 3: Finished
Task 5: Cancelling

When the cancellation token is signalled the tasks have to cooperate. Tasks 1 to 4 are too far gone and will run to completion. Task 5, which was only just started, cooperates with the cancellation request and writes that it is cancelling. No waiting tasks are started.

In the main thread, the control is blocked until all the tasks have either finished or cooperate with the cancellation request. Once the WaitAll unblocks the program handles any cancelled tasks in the catch block.

Handling cancellation of task 9
Handling cancellation of task 8
Handling cancellation of task 7
Handling cancellation of task 6
Handling cancellation of task 5

Tasks 6 to 9 never got a chance to start. Task 5 was started, but was cancelled. Therefore task 5′s cancellation can be handled inside the task and outside it. Different clean up may be required in each place.

Finally, the program lists the end state (See also: Task state transitions) of each of the tasks:

Tasks 1 state: RanToCompletion
Tasks 2 state: RanToCompletion
Tasks 3 state: RanToCompletion
Tasks 4 state: RanToCompletion
Tasks 5 state: Canceled
Tasks 6 state: Canceled
Tasks 7 state: Canceled
Tasks 8 state: Canceled
Tasks 9 state: Canceled
Program End

When writing code to handle cancelled tasks, watch out for this gotcha that can trip you up if you are not careful.

DDD Scotland Parallelisation Talk Overview

DDD Scotland 2011 Talk Opening Slide

Follow Up

I was asked a question during the talk I wasn’t immediately able to answer which I’ve now found the definite answer. What happens to parallel tasks running in the background when the application exits?

Examples

Here are all the examples from Saturday’s introductory talk on Parallelisation at DDD Scotland 2011.

Slide Deck

The slide deck is also available as a PDF file (3.0 Mb)

Scottish Developers Parallelisation Talk Overview

Talk Opening Slide

Here are all the examples from this evening’s introductory talk on Parallelisation at Scottish Developers.

The slide deck is available as a PDF file (10.5Mb)

Parallelisation Talk Example – Aggregate Exceptions

The two code examples here show what happens when exceptions are thrown within tasks that are not handled within the task. In each case the task that has the error throws an exception.

In the first example, only one task throws an exception. Although from the output you can see that more tasks were expected to be launched the framework no longer schedules tasks to be started once an exception is thrown. Any existing tasks are continued to completion.

In the second example, all the tasks will throw exceptions. This is just to show that the aggregate exception is bringing back all the exceptions from the various tasks that were running.

Code Example 1 : Some bad

class Program
{
    static void Main(string[] args)
    {
        List<HotelRoomAvailability> hotelList = GetHotels();

        Console.WriteLine("These are the hotels to process");
        foreach(var hotel in hotelList)
            Console.WriteLine(hotel.HotelCode);

        Console.WriteLine(new string('=',79));


        try
        {
            Parallel.ForEach(hotelList, item => PopulateDetails(item));
        }
        catch (AggregateException aggex)
        {
            Console.WriteLine(aggex.Message);
            foreach(Exception ex in aggex.InnerExceptions)
                Console.WriteLine(ex.Message);
        }


        Console.WriteLine("Program finished");
        Console.ReadLine();

    }

    private static void PopulateDetails(HotelRoomAvailability hotel)
    {
        Console.WriteLine("Populating details of {0}", hotel.HotelCode);
        hotel.Name = HotelRespository.GetHotelName(hotel.HotelCode);
        hotel.Rates = AvailabilityRespository.GetRateInformation(
            hotel.HotelCode, hotel.StayDate, hotel.NumberOfNights);
    }

    private static List<HotelRoomAvailability> GetHotels()
    {
        List<HotelRoomAvailability> result = new List<HotelRoomAvailability>
            {
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONSOHO"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONLHRT4"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONLHRT5" // Not valid
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONWATERL" // Not valid
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONLHR123"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONCOVGDN"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONCTYAIR"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONLEISQR"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONPADDIN" // Not Valid
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONHIGHOL"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONKINGSX"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LONEUSTON"
                    }
            };

        return result;
    }
}

Output

The following is output first

These are the hotels to process
LONSOHO
LONLHRT4
LONLHRT5
LONWATERL
LONLHR123
LONCOVGDN
LONCTYAIR
LONLEISQR
LONPADDIN
LONHIGHOL
LONKINGSX
LONEUSTON
========================================================
Populating details of LONSOHO
Populating details of LONWATERL
Populating details of LONCTYAIR
Populating details of LONHIGHOL
Populating details of LONLHRT4

 

Aggregate Exception Example - Before

Then an exception is thrown

Aggregate Exception Example - Exception Assistant

And the final output looks like this:

These are the hotels to process
LONSOHO
LONLHRT4
LONLHRT5
LONWATERL
LONLHR123
LONCOVGDN
LONCTYAIR
LONLEISQR
LONPADDIN
LONHIGHOL
LONKINGSX
LONEUSTON
========================================================
Populating details of LONSOHO
Populating details of LONWATERL
Populating details of LONCTYAIR
Populating details of LONHIGHOL
Populating details of LONLHRT4
One or more errors occurred.
The hotel code 'LONWATERL' does not match a known hotel
Program finished

 

Aggregate Exception Example - After

Code Example 2 : All bad

This example replaces the GetHotels method, above, with a method that creates a list of entirely non-existant hotels:

class Program
{
    static void Main(string[] args)
    {
        List<HotelRoomAvailability> hotelList = GetHotels();

        Console.WriteLine("These are the hotels to process");
        foreach(var hotel in hotelList)
            Console.WriteLine(hotel.HotelCode);

        Console.WriteLine(new string('=',79));


        try
        {
            Parallel.ForEach(hotelList, item => PopulateDetails(item));
        }
        catch (AggregateException aggex)
        {
            Console.WriteLine(aggex.Message);
            foreach(Exception ex in aggex.InnerExceptions)
                Console.WriteLine(ex.Message);
        }


        Console.WriteLine("Program finished");
        Console.ReadLine();

    }

    private static void PopulateDetails(HotelRoomAvailability hotel)
    {
        Console.WriteLine("Populating details of {0}", hotel.HotelCode);
        hotel.Name = HotelRespository.GetHotelName(hotel.HotelCode);
        hotel.Rates = AvailabilityRespository.GetRateInformation(
            hotel.HotelCode, hotel.StayDate, hotel.NumberOfNights);
    }

    private static List<HotelRoomAvailability> GetHotels()
    {
        List<HotelRoomAvailability> result = new List<HotelRoomAvailability>
            {
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "BRISTOL"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "BIRMINGHAM"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "MANCHESTER" // Not valid
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LIVERPOOL" // Not valid
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "CARLISLE"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "CAMBRIDGE"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "OXFORD"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "READING"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "LEEDS" // Not Valid
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "NEWCASTLE"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "EDINBURGH"
                    },
                new HotelRoomAvailability
                    {
                        StayDate = new DateTime(2011, 7, 1),
                        NumberOfNights = 3,
                        HotelCode = "GLASGOW"
                    }
            };

        return result;
    }
}

Output

These are the hotels to process
BRISTOL
BIRMINGHAM
MANCHESTER
LIVERPOOL
CARLISLE
CAMBRIDGE
OXFORD
READING
LEEDS
NEWCASTLE
EDINBURGH
GLASGOW
============================================================
Populating details of BRISTOL
Populating details of LIVERPOOL
Populating details of OXFORD
Populating details of NEWCASTLE
Populating details of BIRMINGHAM
One or more errors occurred.
The hotel code 'LIVERPOOL' does not match a known hotel
The hotel code 'OXFORD' does not match a known hotel
The hotel code 'NEWCASTLE' does not match a known hotel
The hotel code 'BIRMINGHAM' does not match a known hotel
The hotel code 'BRISTOL' does not match a known hotel
Program finished

More Information

Follow

Get every new post delivered to your Inbox.

Join 25 other followers