Tuesday, June 13, 2017

NodeJS with HBase via HBase Thrift2 Part 1: Connect

Motivation


In each their own, both NodeJS and HBase are power full tools. NodeJS for spining efficient apis up fast, and HBase for holding large amount of data(in somewhat it's own way). More important HBase also solves the small file issue on Hadoop. So combining them can make sense. But it is fairly not documented.

HBase comes with a REST API and a Thrift API. Where the Thrift API is the most efficient, despite that the REST API is returning instantiated javascript objects (hence JSON). The reason is, Thrift is utilizing binary transmission and which more compact than JSON which is utilized by the REST API. There is an older github page with some benchmarking: https://github.com/stelcheck/node-hbase-vs-thrift 

The at-the-time-writing, the latest stable version of HBase is version 1.2.6, it has 2 Thrift interfaces, called: HBase Thrift and HBase Thrift2. HBase Thrift is more general/administrative purpose, where tables can be created, deleted and data manipulated. The stuff I prefer to do in the HBase Shell, and not from a service. HBase Thrift2 is data only, CRUD and even batch operations which are not found in HBase Thrift. 

HBase Part

To make this post complete, we'll go from table creation in HBase, to a connection to it, from NodeJS.


Table creation in HBase from the HBase shell

 create_namespace 'foo'  
 create 'foo:bar', 'family1'  

Start HBase Thrift2 API from OS shell

 bin/hbase-daemon.sh start thrift2  

NB! By default HBase Thrift and HBase Thrift2 are setup to use port 9095 and 9090. I you want them to run concurrent, it is possible set custom port numbers for the APIs

NB! HBase Thrift API can crash due to lack of heap memory, the heap memory can be increased in the config file: conf/hbase-env.sh
 # The maximum amount of heap to use. Default is left to JVM default.  
 export HBASE_HEAPSIZE=8G  

Good to go

NodeJS part

Pre-requisites, besides from having NodeJS installed, is the Thrift compiler and the HBase Thrift definition file. A Thrift definition file acts as a documentation file and a definition file for building service/client proxies.

Thrift compiler can be found on Apache's Thrift homepage: https://thrift.apache.org/ 
HBase Thrift definition file can be found in the HBase source package from the HBase homepage: https://hbase.apache.org/

Start the NodeJS project and add the Thrift package

 mkdir node_hbase  
 cd node_hbase  
 npm init  
 npm install thrift  

Create the proxy client package from the HBase Thrift definition file

 thrift-0.10.0.exe --gen js:node hbase-1.2.6-src\hbase-1.2.6\hbase-thrift\src\main\resources\org\apache\hadoop\hbase\thrift2\Hbase.thrift  

Create the index.js file (you can call what ever you want)

 var thrift = require('thrift');  
 var HBaseService = require('./gen-nodejs/THBaseService.js');  
 var HBaseTypes = require('./gen-nodejs/HBase_types.js');  
 var connection = thrift.createConnection('IP or DNS to your HBase server', 9090); 
 
 connection.on('connect', function () {  
   var client = thrift.createClient(HBaseService, connection);  
   client.getAllRegionLocations('foo:bar', function (err, data) {  
     if (err) {  
       console.log('error:', err);  
     } else {  
       console.log('All region locations for table:' + JSON.stringify(data));  
     }  
     connection.end();  
   });  
 });
  
 connection.on('error', function (err) {  
   console.log('error:', err);  
 });  

Run the js script and get some result

 node index.js  
 All region locations for table:[{"serverName":{"hostName":"localhost","port":49048,"startCode":{"buffer":{"type":"Buffer","data":[0,0,1,92,160,234,132,254]},"offset":0}},"regionInfo":{"regionId":{"buffer":{"type":"Buffer","data":[0,0,0,0,0,0,0,0]},"offset":0},"tableName":{"type":"Buffer","data":[102,111,111,58,98,97,114]},"startKey":{"type":"Buffer","data":[]},"endKey":{"type":"Buffer","data":[]},"offline":false,"split":false,"replicaId":0}}]  





Sunday, March 6, 2016

Hadoop from scratch notes: Preparing a minimal CentOs Linux Hyper-V image

Motivation

Hadoop on virtual machines? These posts are describing how to setup a hadoop homelab, to get in touch with hadoop. Yet, replace 'virtual' with 'dedicated physical', then you should by on your way to build a production cluster.

Hadoop is yet another good tool in the toolbox, when working with data. Now a days Hadoop is available as cloud service, but it can be pretty expensive, and specially if you just want to train and play with Hadoop. Some vendors as Cloudera offers a single node 'play' version of Hadoop, which is a great way to start. Yet the reason I'mt writing these notes, was that I did find Cloudera very closed and slow, and also I had to use any other Virtual Machine system than Hyper-V. Also it is not that hard to set up a Hadoop node or cluster from scratch.

Not that, I have anything against e.g. Virtual Box. Even thou I see all OS'es as my play grounds, I'm in a Microsoft period(due to my current work), and thereby my Windows box is best suited for virtualization. And it does already comes with Hyper-V, and it actually works good in Windows 10(Earlier versions did lock the CPU clock cycle, and thereby disabled speed-step). I like my machines light, so I would hate to have more than one system for virtualization.

What is the goal?

The goal is to prepare a virtual machine with a minimal version of Centos Linux. The reason, I have selected Centos OS is, it is supported by Microsoft, and it is Azure certified, and when it is Azure certified, it means it can work better with Hyper-V through Hyper-V Integration Services. I could have chosen Ubuntu (Azure's Hadoop cloud solution runs on Ubuntu), but I had a challenge with a very slow apt-get, and generally did find CentOS more light weight.

When we have a fully configured virtual machine, with CentOS and Hadoop, we are going to use it as a template, for creating more Hadoop nodes.

I prefer to setup Hyper-V with PowerShell, it is good fun and practice, and it more compact than images of the GUI. If you are familiar with the Hyper-V GUI, then you should have no trouble to figure out what to press.

Before we start, make sure Hyper-V is enabled, and get CentOS from here https://www.centos.org/download/, the minimal ISO should be sufficient(CentOS 7 is currently the latest version).

A virtual switch

If you don't have a virtual switch configured in Hyper-V, you have to configure one. You are going to use it for connecting you Hadoop nodes, the internet and you working machine together. Thou the internet is optionally. Creating a so-called external virtual switch called "Virtual Switch" (Yes, I know, the creative name is striking :-) ), is done by typing following PowerShell:

New-VMSwitch -Name "Virtual Switch" -NetAdapterName "Wi-Fi" -AllowManagementOS 1

As NetAdaptorName use "Wi-Fi" or "Ethernet", depending on which NIC provides internet.

The virtual machine and disk

Often the virtual machine and the disk interpreted as one, but,  a virtual machine consist of the "Machine" and "disk image" with the OS, and further, of some data disks". We are going to create the machine and OS disk in one go. 

New-VM -Name "Hadoop01" -MemoryStartupBytes 4GB -NewVHDPath D:\VMs\Hadoop01.vhdx -NewVHDSizeBytes 10GB -SwitchName "Virtual Switch"

Memory (4 GigaBytes) and disk (10 GigaBytes) sizes are dymanic by default, but the machine is only configured with 1 CPU. It can be upgraded with:

Set-VMProcessor -VMName Hadoop01 -Count 2

Make the virtual DVD point to the download CentOS image:

Set-VMDvdDrive -VMName Hadoop01 -Path D:\Downloads\CentOS-7-x86_64-Minimal-1511.iso

Let's go:

Start-VM Hadoop01

You have to connect to the virtual machine by the Hyper-V GUI-

Installing CentOS

Press Enter. I might take a while, before reaching next step



Select your preferred language


Check that the properties circled with yellow, are correct. That will make thing easier for you in generel. The properties circled with red, are critical, so make sure to read below how to set them.

Press 'Done', that is all

Turn on the network. Failing to do this, can require you to turn it on, after every reboot.

Set the root password. Create a user for good practice.

After installation and reboot. Log in, so we can get the IP address of our new machine, by typing the following command(ifconfig is not available on CentOS minimal)

ip addr

 Note the IP address, it can be found under Eth0: 
We are not going to use the Hyper-V viewer further. It can't copy-paste between guest and host, and the proper way to connect to a Linux/Unix server is via a SSH client. I recommend Putty (http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html), but the Git Bash is just as fine.
Type in the IP and press Open.

If using the Git Bash, you can write:

ssh <ip> -l <user>

Where <IP> is the noted IP and <user> is either root or the user created earliere.

Installing/Upgrading Microsoft Linux Integration Services(LIS)

We don't have much in the CentOS minimal, and Microsoft haven't made it easy to download the LIS package without a browser.
Fortunately, it is GNU licensed, so I have made a script to get it from my GitHub account, and to install it, together with wget.

curl -O https://raw.githubusercontent.com/ChristianHenrikReich/automation-scripts/master/centos-minimal/install-hyperv-essentials.sh

chmod 755 install-hyperv-essentials.sh

sudo ./install-hyperv-essentials.sh

When the script is done. The Virtual machine is fully Hyper-V prep'ed and ready to go. And can be used to other things than Hadoop also.

Next: How to install Hadoop on the image

Sunday, May 3, 2015

Adding schema when using ASP.NET 5 Identity with Entity Framework 7

The post is regarding bleeding edge technology(Entity Framework 7-beta 4), and can be outdated in a foreseen future.

Good database design is when responsibilities are separated, or else your ends up with a monolith trash bin database. The best way to achieve separation of responsibilities, is to have each responsibility in its own database, and disable cross querying. That will be a database for Accounts, Products, Emails etc depending of your business and its domain. One database for each domain.

In these cloud days, that be quite expensive. So we can settle with the next best. Schemas. The must famous schema on SQL Server is dbo. It is the default schema, and sadly, it is used in 99% of the cases, when schemas is applied.

When using ASP.NET 5 Identity with Entity Framework 7 and with Migrations, you will see the tables are putted in the dbo schema. Changing this behavior, is not straight forward.

The solution

You might recognize it. It is the code from template when creating an ASP.NET 5 Web site. Thou I have removed a little. I want to have the identity tables in the schema Accounts.

1. First override the OnModelCreating(Modelbuilder builder) method.

 using Microsoft.AspNet.Identity.EntityFramework;  
 using Microsoft.Data.Entity;  
 namespace Example.Models  
 {  
   public class ApplicationUser : IdentityUser  
   {  
   }  
   public class ApplicationDbContext : IdentityDbContext<ApplicationUser>  
   {  
     public ApplicationDbContext()  
     {  
     }  
     protected override void OnModelCreating(ModelBuilder builder)  
     {  
       // Remenber to Create Schema in DB, until EF7 can handle Schemas correctly  
       builder.Entity<ApplicationUser>().ForRelational().Table("AspNetUsers", "Accounts");  
       builder.Entity<IdentityUserClaim<string>>().ForRelational().Table("AspNetUserClaims", "Accounts");  
       builder.Entity<IdentityUserLogin<string>>().ForRelational().Table("AspNetUserLogins", "Accounts");  
       builder.Entity<IdentityUserRole<string>>().ForRelational().Table("AspNetUserRoles", "Accounts");  
       builder.Entity<IdentityRole>().ForRelational().Table("AspNetRoles", "Accounts");  
       builder.Entity<IdentityRoleClaim<string>>().ForRelational().Table("AspNetRoleClaims", "Accounts");  
       base.OnModelCreating(builder);  
     }  
   }  
 }  

2. This step might not seem gracefully, because it should be fully handled by Migrations in Entity Framework. But schemas and Entity Framework 7, is currently not working as desired. And it is not working with Migrations

Go to SQL Server Management Studio. If your database is not created at this point, create it. Then run CREATE SCHEMA <schema name>. In this case it will be CREATE SCHEMA Accounts. As mentioned, this part should have been handled by Migrations.

3. Run Migrations

4. Continue with your project :-)

Taken this a step further, it could be considered; having a DbContext for each domain of you app, and each of these contexts could have their own schemas.

Wednesday, April 29, 2015

Keeping your Azure Website warm and up to speed

So, you have deployed a web app to an Azure Website. As one might expect, the first web site request is slow, it might take 10 seconds  or maybe even more to respond. It is because the web site is unloaded(cold) and it has to load in(warm up). This first request loads the site, and when it is loaded, it responses quite fast(depending on our code).

But after a period(around 30 minutes) with idle traffic, your web site unloads again. And again to get it loaded again, it needs an request. And again it takes time to load it.

In the Basic and Standard plans for Azure websites, you can disable this feature by setting the Always On option. That was a quick fix :-). If you are using Free or Shared Azure Websites, you can consider following strategies:
  1. Do nothing, if you can live with it. Also If/When your site is frequently visited, it is not an problem. It is only websites with low traffic, such as new sites, suffers from this issue.
  2. Use one of these 'Ping my add' services on the web to request your site. I'm quite sure, this is a solution you should avoid.
  3. Find/own/borrow/invent a machine which is on 24/7 and setup a job to make a request to your site every 5-10 minute.
  4. Keep it all in Azure, Create an Azure Webjob to make a request to your site every 5-10 minute.

I'll explain solution 4, it might have some cons regarding pricing, but I'll cover that.

Azure WebJobs

Azure WebJobs can handle following extensions:

.cmd, .bat, .exe, .ps1, .sh, .php, .py, .js, .jar

I'll show an example, with C# where we are making a console .exe file. The Azure WebJob code:

 using System.Net;  
 namespace HeartBeat  
 {  
   class Program  
   {  
     static void Main(string[] args)  
     {  
       var WebReq = (HttpWebRequest)WebRequest.Create(string.Format("http://<your site>/special_ping_endpoint"));  
       WebReq.Method = "GET";  
       WebReq.GetResponse();  
     }  
   }  
 }  

Now, this is important. Do not ping your landing page, eg. www.example.com, it might cost more resources, specially if you landing page makes web call and database lookups behind the scenes. It might be noticeable on your Azure bill. Create a special minimal endpoint for the purpose, and make it return empty.

An example of such endpoint in

ASP.NET MVC 5 and prior
 using System.Web.Mvc;  
 namespace ActionHandlers.Controllers  
 {  
   public class PingController : Controller  
   {  
     public ActionResult Get()  
     {  
       return new EmptyResult();  
     }  
   }  
 }  


Or ASP.NET 5 MVC 6
 using Microsoft.AspNet.Mvc;  
 namespace ActionHandlers.Controllers  
 {  
   public class ExampleController : Controller  
   {  
     public IActionResult Get()  
     {  
       return new EmptyResult();  
     }  
   }  
 }  


Azure WebJob considerations regarding costs

The WebJob is the thing which properly is going to cost you, but it depends. Azure WebJobs is dependent of Azure Scheduler, and Azure Scheduler comes in 3 plans: Free, Standard and Premium. The biggest difference regarding to our case, is how frequent a job can run. With the free plan, a job can run once in an hour, while for Stardard and Premium, they can run once in a minute.

So with a newly created web site, it would be optimal with the standard plan and ping every 5-10 minute, for keeping your site warm. But it is a bit pricy. But you could use the free plan and do a ping every hour and hoping to have a visit after 15-30 minuttes after the ping, then your site is properly warm until next ping. You could consider following strategies, for keeping your site warm.
  1. Completely new and fresh website: Traffic is going to be very light, use the standard plan
  2. Website with light traffic: Use the free plan
  3. Website with often traffic: No plan.
Using Free or Shared Websites with a Azure Scheduler, it still cheaper than switching to Basic Websites and use Always On. Also, using a scheduler should only be a temporary solution, until you site has good traffic. 

Alternative WebJob way

Making an Azure WebJob, with a thread sleep for 5-10 minuttes and run it continuously without a scheduler, is not a recommendable solution. Because Azure is able to unload websites with associated unscheduled WebJobs.

WebJob Installation

Put you WebJob code into a zip, in our case it will be the compiled exe and config file, from either the Debug or Release folder in your Visual Studio Project (I'll take the liberty to assume, your using Visual Studio).

Go to the Dashboard for you Website, and find the WebJob tab. Add the WebJob.

Custom Action Results in ASP.NET 5 (VNEXT) (MVC6)

Before we start, you should be aware of this. This post is based on a the ASP.NET 5 version, Visual Studio 2015 CTP 6 pulls down, when it creates an ASP.NET 5 Project. Meaning it is a pre-release of ASP.NET 5. Things in ASP.NET 5 can change and outdate this post. It is highly unlikely, but it can happen.

Even thou I keep referring MVC 6, it is still a post regarding ASP.NET 5 or ASP.NET vNext, it's the same, and MVC 6 is a part of ASP.NET MVC 5.

Why would I write a custom ActionResult

Yes, good question. There is plenty supported in ASP.NET 5. But sometimes you ends up in a situation, where you need something special. When I developed Your Favorite Snippet Tool, I needed to transfer binary in a certain way, to provide best user experience. I created a custom ActionResult to handle it.

ActionResult in MVC 6 compared to earlier versions

ActionResults have changed a bit, since the prior versions of MVC. Yes, you still have to inherit from ActionResult and yes you still have to override a ExecuteResult method, when making custom ActionResults.

The most noticeable difference, is that in MVC 6 ExecuteResult have another signature compared to prior version, and there is also a ExecuteResultAsync added.

ExecuteResult for ASP.NET MVC 5 and Prior


public abstract void ExecuteResult(ControllerContext context)

ExecuteResult for ASP.NET MVC 6


public virtual Task ExecuteResultAsync(ActionContext context)
public virtual void ExecuteResult(ActionContext context)

Two thing you might notice, the methods in MVC 6 are using virtual methods, and ActionContext instead of ControllerContext. There is nothing much to say about the contexts, they are very similar. By using virtual method there is no override constrains. It means that you can override either ExecuteResultAsync, ExecuteResult or both, but are not forced to.

Which to override, ExecuteResultAsync or ExecuteResult

It depends, but preferly ExecuteResultAsync, because it is the one which is called. Inside ActionResult, which you have to inherit from, following logic is happening:

 public abstract class ActionResult : IActionResult  
   {  
     public virtual Task ExecuteResultAsync(ActionContext context)  
     {  
       ExecuteResult(context);  
       return Task.FromResult(true);  
     }  
     public virtual void ExecuteResult(ActionContext context)  
     {  
     }  
   }  

So you see, ExecuteResultAsync is still called even thou you just override ExecuteResult. Plus, it will not make sense, to enforce overrides of the 2 methods.


Show me some code

I have made a string writer result, not the most exciting example, but it proves the point.

The custom ActionResult

 using Microsoft.AspNet.Mvc;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace CustomActionResults  
 {  
   internal class StringWriterResult : ActionResult  
   {  
     private byte[] _stringAsByteArray;  
     public StringWriterResult(string stringToWrite)  
     {  
       _stringAsByteArray = Encoding.ASCII.GetBytes(stringToWrite);  
     }  
     public override Task ExecuteResultAsync(ActionContext context)  
     {  
       context.HttpContext.Response.StatusCode = 200;  
       return context.HttpContext.Response.Body.WriteAsync(_stringAsByteArray, 0, _stringAsByteArray.Length);  
     }  
   }  
 }  


String write ActionResult in action:

 using CustomActionResults;  
 using Microsoft.AspNet.Mvc;  
 namespace ActionHandlers.Controllers  
 {  
   public class ExampleController : Controller  
   {  
     public IActionResult Get()  
     {  
       return new StringWriterResult("Hello World!");  
     }  
   }  
 }  

Insert the code in some ASP.NET 5 project, and you should get Hello World!, when hitting ~/Example/Get.


Monday, April 27, 2015

Introducing Your Favorite Snippet Tool

Snippets in Visual Studio and SQL Server Management Studio are a great help, and tremendous time savers. Unfortunately the con about VS and SSMS snippets are: They are tedious to create. I have a feeling, that makes it less appealing to use custom snippets, because it includes working with XML to create them, and VS or SSMS offers no help.

History

Well, a couple of days ago, I decided to make a snippet of some SQL, which I had realized, I had to write regularly in the future. I was pretty tired of writing this SQL, and then I remembered: To create a snippet you have to setup an XML document. Then I got really tired. In hope of an easy solution, I did search the web for an online snippet creator. All i did find was tools, which had to be downloaded. No offence, these downloadables are properly mighty fine, but nowadays I think a tool like a snippet creator should be online. Easy to reach, and not another downloaded tool to soil your computer.

Priorities can be strange some times, and I decided, that I would rather write an online tool myself, which could make snippets, than do another handmade snippet.

So here after a small coding marathon, I'll present to you:

YOUR FAVORITE SNIPPET TOOL(that is the name)



Enjoy!

FAQ

Q: Why is the link www.snippettool.net and not www.yourfavoritesnippettool.com when the tool name is Your Favorite Snippet Tool?
A: For your convenience. It is much easier, to remember www.snippettool.net and type it right. 

Q: The first release is version 0.8.0, is it production ready?
A: Yes. There is some extended features for VB, which will be there in a later release. Further I have some ideas for UI improvements. Also, until I have had some more feedback, it wouldn't be right to release it in version 1.0.0

Q: VSI packages are supported, what about VSIX packages?
A: VSIX does not by default, support snippets. Hacks must be applied to make VSIX work with snippets.

Q:The Visual Studio Content Installer does not install the VSI package to Visual Studio 2xxx, why?
A: That is because, Visual Studio Content Installer is a strange piece of software. Specially, if you have more versions of Visual Studio on your machine.

Q: I found a bug, what to do?
A: I will appreciate, if you would write to me about it. Contact information is at the button of the page. 


Saturday, April 11, 2015

SSIS: An easy SCD optimization for dev and prod

The value of reading this post, depends on how you work with SSIS and how database nursing are handled in within your organization.

The optimization is a single index, but if you only nurse indexes in prod, you could waste a great time when developing SCDs in SSIS. The method is simple, when you now the nature of your SCD, then you can create an index right away, and reduce your development waiting time. Specially if you are testing with bigger volumes of data.

Let me show you

Let's say you have following table definitions, and you working in a SSIS project using Visual Studio:

-- Staging
CREATE TABLE Staging.Customers
(
CustomerId UNIQUEIDENTIFIER,
FistName NVARCHAR(200),
MiddleInitials NVARCHAR(200),
LastName NVARCHAR(200),
AccountId INT,
CreationDate DATETIME2
)
GO 

-- Dimension
CREATE TABLE dbo.dimCustomers
(
CustomerDwhKey INT IDENTITY(1,1),
[Current] BIT, 
CustomerId UNIQUEIDENTIFIER,
FistName NVARCHAR(200),
MiddleInitials NVARCHAR(200),
LastName NVARCHAR(200),
AccountId INT,
CreationDate DATETIME2
CONSTRAINT PK_CustomerId PRIMARY KEY CLUSTERED (CustomerDwhKey)
)
GO


You have a Data Flow, where you transfer data from Staging.Customers to the dimension dbo.dimCustomers using the built-in component Slowly Changing Dimension:


In our example setup CustomerId will be a so-called Business key, And Current will be the indicator for which row are current. It should also be noted, it is possible to have more than one Business keys.


We'll configure attributes as:


Now, the Slowly Changing Dimension component work in following way:

For each entity it recieves, it will search the dimension table for an entity with the same business keys(in plural!!!) and is flagged as current, or in plain SQL:

SELECT  attribute[, attribute] FROM dimension_table WHERE current_flag = true AND business_key = input_business_key[, business_key = input_business_key]

Or as it will look like in our example

SELECT AccountId, CreationDate, FirstName, MiddleInititals, LastName FROM dbo.dimCustomers WHERE [Current] = 1 AND CustomerId = some_key

Further, in case we have an historical change, the current entity in the dimension must be expired by setting Current = 0.

UPDATE dbo.dimCustomers SET [Current] = 0 WHERE [Current] = 1 AND CustomerId = some_key 

The solution

As you might have realize by now, we can improve performance tremendously by putting an index on the current flag and the business keys(again plural!!!). For each entity passing through the Slowly Changing Dimension component, the will be at least 1, but likely 2 searches in the dimension table. And the by knowing the business keys and current flag. and the nature of the Slowly Changing Dimension component, you can predict the index which will improve performance.

The index for our sample will be

CREATE NONCLUSTERED INDEX IX_Current_CustomerId ON dbo.dimCustomers
(
[Current],
CustomerId --- Remember to include each business key
)

Should index be a filtered? I'll let that be up to you.

Indexes, bulk and loading of dimensions

Some tend to drop indexes when loading dimenson, with the argument: Bulk loading is fastest without indexes, which SQL Server has to maintain while loading. This argument has to be revised when working with the Slowly Changing Dimension component.

Because the component searches the dimensions so heavily, (in general) it will be faster loading with indexes than without. If there is no indexes, each entity going through the component, will require at least one table scan, which is quite expensive, and gets more expensive as your dimension grows. 

That's all

Monday, March 9, 2015

Wrestling the Azure Storage REST API - Part 2

This post is about authorization HTTP header, used when making requests to Azure Storage API. There is some dependencies the previous part of this series, specially regarding the x-ms-date header field.

Authorization

The authorization field is expressed in this way:

Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"

The authorization supports 2 schemes for calculating signatures, Shared Key or Shared Key Lite. The scheme you are using for authorization must be stated with either SharedKey or SharedKeyLite as the first thing in the header field.

The difference between the schemes are, Shared Key Lite is backward compatible with earlier versions of the Azure Storage API. I can't remember to have seen any example with Shared Key, I guess it is because it requires more effort to make it work.

Important!!! When using dates in authorization, these dates must be the same as x-ms-date, or else the authorisation will fail.

Shared key

Blob, Queue and File Storage signature is calculated one way, while Table Storage signature is calculated in another way. 

Blob, Queue and File Storage:

StringToSign = 
VERB + "\n" +
Content-Encoding + "\n" +
Content-Language + "\n" +
Content-Length + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
If-Modified-Since + "\n" +
If-Match + "\n" +
If-None-Match + "\n" +
If-Unmodified-Since + "\n" +
Range + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;

Table Storage:

StringToSign = 
VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" + 
CanonicalizedResource;

Shared key Lite

Like Shared Keys, there is a difference in calculating the keys depending on what kind of storage is used:

Blob, Queue and File Storage:

StringToSign =
VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;

Table Storage:

StringToSign = 
Date + "\n" +
CanonicalizedResource

When comparing the 2 schemes, it begins to make sense why most chose to use Shared Key Lite

Which parameter must be filled, depends heavily on context. E.g. Date, while it must be set in every Table request, there is some Blob requests where it must not be set.

Canonicalized Headers

Just take all the header starting with x-ms-, sort them and concatenate them separated by \n.

Exmaple(taken from the Azure Storage documentation):

 x-ms-date:Sun, 20 Sep 2009 20:36:40 GMT\nx-ms-meta-m1:v1\nx-ms-meta-m2:v2\n

Canonicalized Resources

Canonicalized resources is form the following way:

Canonicalized resource = /account/resource

Example:

For this request

GET https://myaccount.table.core.windows.net/Tables HTTP/1.1

The canonicalized resource will be /myaccount/Tables

Query parameters must not be included. Unless you make following request(taken from documentation):

GET https://<account-name>.table.core.windows.net/?restype=service&comp=properties HTTP/1.1

Here the canonicalized resource will be /myaccount/?comp=properties

Calculating the signature

Here is the Azure Storage REST API documentation pretty weak. 2 things it misses are, when using HMAC you need to supply a key and a message. In context of making requests to the Azure Storage REST API, the key is either the Primary og Secondary key, which can be obtain from the Azure portal. The message is the StringToSign defined earlier in this post.

Also, the Primary and Secondary key which is found on the Azure portal are base64 encoded, you need to decode them, in order to be able to use them.

So what the documentation states as

Signature=Base64(HMAC-SHA256(UTF8(StringToSign))) 

Is in reality


Signature=Base64(HMAC-SHA256(UTF8(Debase64(key)),UTF8(StringToSign))) 

Where key is either the Primary or Secondary key.

And this is all for Authorization.

Wrestling the Azure Storage REST API - Part 1

Motivation

With Azure SDKs for a wide variety of programming languages, why should anybody want to learn about the Azure Storage REST API? 

Maybe there is no SDK for your favourite language, which was my case. Maybe the official SDK do not support the latest API version, which could mean it is not possible to communicate with JSON in Table Storage. Maybe you are just courios.

This blog post is based on my work on GoHaveAzureStorage, and hopefully you will also gain from challenges I have had the Azure Storage.

Request break down 

A REST call looks like this:

GET https://myaccount.table.core.windows.net/Tables HTTP/1.1

This request is used to get all tables for an storage account. There is 2 mandatory http header fields, and an additional optional which I recommend, which you must send for every request to make it work. They are 
  • x-ms-date       - time for the request.
  • x-ms-version  - Which API version is the request targeting
  • authorization  - Which is a security digest
The first 2 header will be explained in this post, while the Authorization will be explained in part 2.

The URL

First the easy part. It is possible to use either HTTP or HTTPS, else it is more or less straight forward.

The x-ms-date header field

This field is used by Azure for validation and authorization. A valid request must be maximum 15 minutes old, and it must not be dated in the future. It can be expressed as:

current time =< x-ms-date < current time - 15

Pro tip

As it is close to impossible to be complete time synchronized with Azure, it is recommend to substract a few minutes from current time, when sending request.

One important last ting, Azure only understands time in RFC1123 format and GMT +0

If you have: Thu, 12 Feb 2015 21:16:45 UTC in a +1 time zone
It must converted to: Thu, 12 Feb 2015 20:16:45 GMT

The x-ms-version header field (Pro tip)

This an optional field, but you should prefer to set it, or else you will hit an earlier version of the Azure Storage API. you might experience challenges with JSON in table storage or with Shared Access Keys if not using the latest version.

The versions are defined as date, The date which the API version is released. I'm not sure wether this a good solution, because I find dates hard to remember after a while compared to versions. So I have to look up once in a while here: https://msdn.microsoft.com/en-us/library/azure/dd894041.aspx



Wednesday, February 11, 2015

Introducing GoHaveAzureStorage

Motivation

In a private project, I wanted to reach Azure Table Storage from some Go applications. My only issue was, I couldn't find a proper Go Azure Table Storage library. So when I got hold on the Azure Table Storage REST API, I decided to do a Go Azure Table Storage lib, and then I decided to do a full Azure Storage lib.

GoHaveAzureStorage

I have used the Microsoft Azure Storage API documentation, as inspiration for the library. With this approach, I hope people who is experienced with programming against Azure will find GoHaveAzureStorage just as easy to use.

A small sample:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
 "fmt"
 "gohaveazurestorage"
)

//Either the primary or the secondary key found on Azure Portal
var key = "PrimaryOrSecondaryKey"

//Storage account name
var account = "Account"

func main() {
 // Create an instance of the lib
 goHaveAzureStorage := gohaveazurestorage.New(account, key)

 // From the lib instace, we can create multiple client instances
 tableStorage := goHaveAzureStorage.TableStorage()

 //Creating a table
 httpStatusCode := tableStorage.CreateTable("Table")
 if httpStatusCode != 201 {
  fmt.Println("Create table error")
 }
}

For documentation and progress of the project:
https://github.com/ChristianHenrikReich/gohaveazurestorage

Tuesday, January 20, 2015

Go: Import cycle not allowed

Level: 1 where 1 is noob and 5 is totally awesome
System: Go

Among the programming languages I use, Go is one of my favorites. Intentionally Go lacks features such as generics, inheritance and some others features, which people might see as standards in a programming language. Some might see this as weaknesses in the language, and some might see it as strengths. In the end, the purpose is the keep the language simple, and to build software with less complex code.

A thing which can be challenging in Go, is object parent-child relations, where a child knows it's parent. Like this code below tries, and fails with an 'Import cycle not allowed' error:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package child

import "Parent"

type Child struct {
  parent *Parent
}

func (child *Child) PrintParentMessage() {
  child.parent.PrintMessage()
}

func NewChild(parent *Parent) *Child {
  return &Child{parent: parent }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package parent

import (
  "fmt"
  "child"
)

type Parent struct {
  message string
}

func (parent *Parent) PrintMessage() {
  fmt.Println(parent.message)
}

func (parent *Parent) CreateNewChild() *child.Child {
  return child.NewChild(parent)
}

func NewParent() *Parent {
  return &Parent{message: "Hello World"}
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import (
  "parent"
)

func main() {
  p := parent.NewParent()
  c := p.CreateNewChild()
  c.PrintParentMessage()
}

Cross-refering packages are not allowed in Go. The best thing would be, if Parent could keep track of the children. Then there would be no issues, and some might argue the code would be more clean. But the world is not perfect, and sometimes circumstances enforces design decisions like this.

To make things work, we can use the nice duck typing feature(interfaces) which Go supports. In general, it is good practice to use interfaces. It keeps the code de-couplet and flexible.

So if we make the interface IParent and use it, then everything works out:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package child

type IParent interface {
  PrintMessage()
}

type Child struct {
  parent IParent
}

func (child *Child) PrintParentMessage() {
  child.parent.PrintMessage()
}

func NewChild(parent IParent) *Child {
  return &Child{parent: parent }
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package parent

import (
  "fmt"
  "child"
)

type Parent struct {
  message string
}

func (parent *Parent) PrintMessage() {
  fmt.Println(parent.message)
}

func (parent *Parent) CreateNewChild() *child.Child {
  return child.NewChild(child.IParent(parent))
}

func NewParent() *Parent {
  return &Parent{message: "Hello World"}
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import (
  "parent"
)

func main() {
  p := parent.NewParent()
  c := p.CreateNewChild()
  c.PrintParentMessage()
}

Now 'Hello World' is written to output, as intended. Of course, the interface can be placed in a 3rd package. As always, it depends...

Saturday, November 15, 2014

Balancing resources in SQL Server

Level: 3 where 1 is noob and 5 is totally awesome
System: SQL Server

As software developer I believe in decoupling, and I'm certain that decoupling is just as important in database design as well. I really like having things in minimum chunks, and keeping them independent as possible. Independence and decoupling equals scalability. This post is based on a professional experience, which supports my belief.

At my work we are developing a billing platform, and this platform has several clients. Each client use our platform to bill a certain amount of customers. So this set the scene.

Some time ago, we had one database for each client in one instance, which is a easy pattern. But in SQL Server it can easily be an expensive anti-pattern, and it is certainly a pattern which is my last choice. The problem with this pattern, it is only effective, when the databases is equal regarding size and usage.

The buffer pool


The explanation is, there is only one buffer pool pr. instance. SQL Server is an in-memory database, but in most cases, there is not enough memory for a whole database in the memory. And if there is more databases in an instance, then it is almost certain there no room in the memory for all the bases. To solve this issue, SQL server has the buffer pool, which is a cache. When querying, SQL Server will get the result from the buffer pool. If it not available in the buffer pool, it reads from the storage to the buffer pool. If there if no room in the buffer pool, it will flush some of the buffer pool, to make room for the requested data. Everything has to go through the buffer pool.

The process of getting data from storage to the bufferpool, generates PAGEIOLATCH waits. A high count of PAGEIOLATCH waits can be a sign of much data is being loaded from disk to the buffer pool.

Let us say, we have 3 databases in one instance. They respectively supports 25.000, 150.000 and 300.000 customers. The sizes of the databases reflects the number of customer, because more customers generates more data. What will happen, is the database with the most usage, will push out the data from the other bases, out of the buffer pool. This will give the lesser bases more read from the disk, producing more PAGEIOLATCH wait, adding more latency to the lesser bases. Actually, the smallest databases will suffer the most.

The poor solution  


I'm tempted to call this, the poormans solution, but it can be very expensive. The solution is to extend the buffer pool, with more memory. But there is a physical and economical limit to this. SQL Server 2014 has a new feature called buffer pool extensions, where it is possible to extends the buffer with storage(preferable SSD drives). I guess extending the buffer pool, will only cache more of the database with most uses. Besides, we have tried this feature, and have yet to see some great results. I would really like to hear, if some has used this feature with success.

The better solution


A easy way to balance databases resourcing over an instance, is by using the resource governor feature in sql server. It works excellent, but it is really a doubled edged sword. Used wrong it can really downgrade performance. It would also require some nursing, which I prefer to keep to a minimum.

The best solution


I find the best solution is to have more instances. If I have 3 clients, I will assign an instance to each, make it thier domain. Each instance, should have hard assigned a certain amount of memory, and their databases would never be able to inflict each others performance. 

This was the solution we did end up with, and it gave us better performance overall. 

  


Wednesday, October 22, 2014

Smart and Useful are not implicit the same

This special topic is something, I do philosophy on often. Why do we see, the smartest solution looses to the less smart solution? Like why did Betamax loose to VHS? Amiga to PC? HD-DVD to Blu-ray? And so on. My conclusion is; people in generel did find the looser less useful, no matter how smart they where compared to the winner.

Our job as developers(I assume you are a developer), no matter sort of developer, is to make the life easier for somebody or some, usually in an organization. At least, making life easier a.k.a. creating value, should be rule number one, for every developer.

I believe most developers understand the business domain, for the job they are hired to do, but I don't believe it is enough. By knowing the business domain, a smart solution can be developed, but is it useful? And what are the difference of smart and useful? I can state it, by making an example of financial data which need to be presented for a CEO.

Let's say the financial data is produced with the finest practices. The code behind is clean code, full maintainable and maybe even very innovative so the data can be produced in half the time as normal. The numbers are spot on error free. The data is presented in XML, so everybody with an understanding of XSLT, can transform it any way the like. It is smart!!! At least from a developer's point of view. But is it useful from a CEO's point of view. I don't think so. For being useful to, the data could have been sent, as an Excel file to the CEO's inbox. Everyone in such position know some degree of Excel, and done completely useful, the CEO should be able to present the report for his peers without further changes. XML and transformation should not be considered CEO knowledge, but Excel could.

My point is, to develop something smart and useful, you should not only know the business domain, you should also know the recipient(s) of your solution.

A good way to know a recipient is to talk with the recipient, and recognise the person's workflow. See if the solution you create, can be easily integrated into the recipient's workflow with little impact as possible, while still solve the recipient's problem and make the life easier for this person. That would be useful. Thing you could consider in advance, could be:


  • If your recipient, are using a coperate computer, then avoid things which means something has to be installed. Sometimes installation of components, is not even possible. Often components often involves regular involvement from support. Try to target you solution to something already on the your recipient(s) computer. E.g. Microsoft office. It will give you less fuzz and frustration.

  • If possible and depending of the type of the recipient, try to push the result of your solution to the recipient. As an example, again consider a report to a CEO. He shouldn't use time on digging out a report from a system you build, it should just be mailed to him. It would fit his busy workflow better. What would be even worse, would be if the system didn't use his OS credentials for logging in as single sign on, but if he had to use a 2nd credentials for this. Then the digging would be much harder. It would have even more negative impact on his workflow.

  • Optimise your result if possible. A report example again, instead of pages full of numbers, try to optimise with graphs in the start of the report. This would point out the important faster. Numbers could be added as appendix if details are needed. Optimise the report, so it is ready for be shown at meetings. CEO it save time, his life is more easy. 

  • Maybe most importantly. As a developer you are often a minority, compared to the number of recipients of your solution. They very seldom have the knowledge and technical insight on your solution as you. They will see your solution from another perspective, and you should respect this and learn from it. It is the key to make your solution more useful.

  • The purpose of education of recipients is to have a win win situation, you have less to do while your recipients would get more value. But educating people is hard, and choose you battles wisely here. E.g. Learning business people reading XML, compared to learning them a new functionality in Excel is tedious. You will often find the urge to learn people something, when they don't have time for it. E.g. When a business man who really need some data, and you have it in XML. The issues here are, his mind is on getting data, not on learning XML, He can't speak XML with his peers, He is not interested in XML at all and so on. On the other, if you extend a tool he already knows or show a feature, so you can provide him silent with XML. Then he would properly be more keen to learn about the tool, and then the education would both help you and him.  
It was few example, but is easy to come up with more.

My examples has primarily been with reporting, but this can be transferred to what ever. The golden rule is basically to know you audience and their habits. 

Thursday, October 2, 2014

SQL Server, SSIS or SSAS: Fastest and easiest way to create a time dimension

Level: 2 where 1 is noob and 5 is totally awesome
System: SQL Server 2005 and above

One of the most vital components of a dataware house, is the time dimension. It also seems to be the part which people to have most difficulties to generate. I seen all from black magic in MS Excel to big complex SQL scripts and even fancy SSIS solutions, just to generate time dimensions.

I do believe, I have found a better solution.

My solution is this script, I have written(inspired from a script I did found on Stack Overflow). You set a start and end date, plus the granularity. My recommendation is to generate times for at least a decade. A decade with the granularity of one hour, takes less than 5 Mb of data storage and 87601 records with this script as default. A decade is generated in a few seconds.


 DECLARE @StartDate DATETIME = '2010-01-01';   
 DECLARE @EndDate DATETIME = '2019-12-31';   
   
 WITH DateTimeGenerator AS  
 (  
  SELECT @StartDate AS DateAndTime  
  UNION ALL  
  SELECT DATEADD(HOUR, 1, DateAndTime) -- Change datepart to ajust granularity, see http://msdn.microsoft.com/en-us/library/ms186819.aspx for more  
  FROM  DateTimeGenerator    
  WHERE  DateAndTime + 1 < @EndDate  
 )  
 SELECT ROW_NUMBER() OVER (ORDER BY DateAndTime) As Id,   
 DateAndTime,   
 DATEPART(HOUR, DateAndTime) AS [Hour],  
 DATEPART(DAY, DateAndTime) AS [Day],  
 DATEPART(WEEK, DateAndTime) AS [Week],  
 DATEPART(MONTH, DateAndTime) AS [Month],  
 DATEPART(QUARTER, DateAndTime) AS [Quarter],  
 DATEPART(Year, DateAndTime) AS [Year]  
 INTO DimTime  
 FROM  DateTimeGenerator  
 OPTION (MAXRECURSION 0)  

Enjoy

Tuesday, June 24, 2014

SQL 2014: Getting started with OLTP, OLAP, SSIS, SSAS and SSRS

As passionate developer, I come in touch with many technologies, but only a few of them has been so tough to crack as SSAS and SSRS. While learning SSIS, I felt i was learning a lot about datawarehousing, and I couldn't really imagine there could be more to it. At the same time I knew there must be more to it, as SSAS and SSRS was a part of the SQL Server suite.

Now I know that SSIS, SSAS and SSRS can be translated to data gathering, data modelling and data visualisation.

And I have written this post to give a swift explenation of SSIS, SSAS and SSRS so it might be easier for you to get started.

My dream database setup 


Starting with a greenfield project, is often difficult. There no experiences and no knowledge, thereby there is paved no road, to go by when developing the system. In my opinion, the 1st mistake which the most make at this point, is to put it all data in same database. This leads to a monolith system, which is hard to maintain and expand. The 2nd mistake is not to divide the database setup in OLTP and OLAP. This lead to analysis with heavy querying in production and passive historic data also stored in production.

OLTP is an acronym for Online Transaction Processing. In other words, it is the database, which is in the line of business. You can also call it, the database with live data. In my dream setup for at system, i would have a bunch micro services, all supported by their own database. Not necessarily relational databases, I would have the database which fitted the job best. The data in these databases, would be on a journey, which ended in a OLAP system. This journey could span from instant to the lifetime of the system.

OLAP is an acronym for Online analytical Processing. OLAP is almost always, analysed for financial reasons, and therefor it should be the last stop for data. It must not return to OLTP, because it would mean, that history could be re-written which is a problem when it comes to finance.

The process of getting data from OLTP to OLAP, would be data gathering, which is the perfect intro for next topic: SSIS.

SQL Server Integration Services (SSIS)


SSIS has become one of my favourite SQL Server tools. With few drag and drops, it is possible to setup data copy or transformation. Compared to scripting(as a developer I usually prefers scripting), it is so much faster to get something up and running, and also easier to structure. Enough praising.

Referring to OLTP about having several different databases, and SSIS being able to read from different source. It is the perfect tool to support this solution.

DQS (Data Quality Service) and MDS (Master Data Service) are often mention together with SSIS. These tool works only with SQL Server, but if you are all-in with SQL Server these tools are quite good. DQS is for correcting data, as they are gathered. MDS is sort of an authority which distribute a data model through out a system to the connected SQL Server database. It makes sure data integrity is kept.

There is other suppliers of ETL tool for SQL Server, but I only use SSIS.

SQL Server Analysis Services (SSAS)


Even thou data is arranged by stars, and it browsable through excel, it can be better. While a star is easy to imagine, it can be more difficult to imagine an cube, and in the beginning even to realize the difference. A cube is like a dimensional system, as we now it from math. Most of us can imagine 1st, 2nd, 3rd dimensional system. Some of us can even imagine a 4th dimensional system, by collapsing 3 dimensions and add a 4th dimension, so it look 2 dimensional again.

Each dim table in a star, would be a dimension in a cube, but they are still not the same. In principle you could take a star, print out all tables, put the papers on a table and then draw lines for each relation from the dimension tables to the fact table. Where a cube is arranged (as mentioned before) an a virtual dimensional system, it is really not printable, but fast for analysing/browsing.

SSAS Helps you building cubes, so that would be data modelling. It will also assist you to do some data mining. I'll will refrain to speak of data mining with SSAS, because I haven't touch that topic yet.

Working with cubes, is a way in SSAS which called dimensional mode. SSAS has two more modes: PowerPivot and Tabular. It is other ways to model data, and which one is best? It depends. 

But with there is no point in having data modelled, if you can't deliver their information in a readable way.

SQL Server Reporting Services (SSRS)


As you might have guessed SSRS is the visualisation part of the SQL Server suite. There not much to say. It easy to design reports with the editor, you can render reports to various formats and make them available from a reporting server or a share point site.


Take advantages of having SSIS, SSAS and SSRS available


SSIS, SSAS and SSRS are available from SQL Server standard, BI and Enterprise. Not using these tools, when having SQL Server licenses which includes them is as failure. Often have I seen, and have properly in past done myself, custom made reports and based on some analysis directly from the production environment. 

Nobody finds it funny to create custom reports and nobody finds it funny to maintain them. So using SSIS, SSAS and SSRS is a win-win, because it would mean full value from licenses, and developers would use less time on reports and more time on funny stuff.


Getting started 


Getting started with SSAS and SSRS, was a bit hard for me, but fortunately I did stumble in the book: Microsoft SQL Server 2014 Business Intelligence Development: Beginner’s Guide by Raza Red. It is real page turner, which is nice, if you reads a lot of books per year.

It is very comprehensive and filled examples, with good explanations, which I like a lot.

Saturday, April 5, 2014

SQL Server 2014: SQL Server Data Tools(SSDT) and Visual Studio 2013 Challenges in Training Kit 70-463 and in general

Level: 2 where 1 is noob and 5 is totally awesome
System: SQL Server 2014

Notice: I'm using the SQL Server 2014 Developer edition, so if you are using a different edition, things might be different.

Some History


I'm currently studying for the exam 70-463 Implementing a Data Warehouse with Microsoft SQL Server 2012, and I'm using the 70-463 training kit for the exam. I have decided to use SQL Server 2014 for the practical training(regarding to SSDT, I now know it is the best to use SQL Server 2014). It has just been released and regarding to exam 70-463 there is no change. People who took the exam for SQL Server 2012 is also certified for SQL Server 2014. For more see FAQ here at http://www.microsoft.com/learning/en-us/sql-certification.aspx.

When using the training kit, you sooner or later realize, it has become a bit outdated. Which is quite natural, because it was published 25. Dec. 2012, and lot have happened since. There has been new releases and updates of Visual Studio, and we even have a new version of SQL Server. Which, all in all is nice.

The first sign of you might be challenged when using the training kit with SQL Server 2014, is in the beginning. The exam kit provides a list of features you have to install, and last on this list is SQL Server Data Tools, also known as SSDT. As you might discover, this feature is not shipped with SQL Server 2014, and it is the most important component for SSIS and the exam 70-463.

SSDT is a Visual Studio plugin, for developing SQL Server Integration Service(SSIS) packages. SSDT is a replacement from Business Intelligence Development Studio, also known as BIDS.Among things, SSDT delivers SSIS packages templates to Visual Studio. SSIS 2012 depends on Visual Studio 2010, Like SSIS 2014 does, but SQL Server 2012 installs the Visual Studio 2010 IDE if none is present. SQL Server 2014 has failed to do so, everytime I have tried to install it. If there is no SSDT in the SQL Server 2014 installation, it might make sense. Also it is okay, because I prefers to use Visual Studio 2013, and if you are a developer like me, I guess you prefer the same.

And Now the Tricky Part


I discovered Microsoft had developed SSDT (SSDT-BI which it is called now) for Visual Studio 2012, it the most easy package to find, and I thought it was the latest. I installed it, and was hit hard in chapter 3 of the training kit 70-463. Because I has installed SSDT-BI 2012 for Visual Studio 2012.

The problem was I have created a SSIS package with the SQL Server Import and Export tool, the version which comes with SQL Server 2014. It stores it SSIS Packages in the SSIS Package format version 8, while the SSDT 2012 stores in the SSIS Package format version 6. The SSIS Package format is apparently not forward compatible. 

The pain I experienced, in chapter 3 of the training kit, was I had to create a package with the SQL Server Import and Export tool (version 2014 in my case) and add it to a SSIS Project created with SSDT 2012. The because the version numbers didn't match, result was this:



Fortunately I succeeded to find SSDT-BI 2014 well hidden at 

It saves SSIS Packages in SSIS Package format version 8, like the rest of the SQL Server 2014 Suite, plus it works with Visual Studio 2013. I'll expect it will work it with the rest of the training kit 70-463, or else I'll provide a solution on this blog. As bonus info, you have to select "Perform a new installation of SQL Server 2014", or you will get some kind of architecture error. Despite the option name, it only installs SSTD-BI 2014.


Enjoy




 

Tuesday, March 18, 2014

Migrating from HaveBox 1.6.1 to 2.0.0

It's here, the lastest version of HaveBox. HaveBox 2.0.0. A bump in the major vision number means there are some breaking changes, when migrating from a prior version of HaveBox.

The breaking changes was needed, to get HaveBox in the direction I wanted. My goal is still to keep HaveBox simple, it doesn't mean less features in the future, but on the other hand I will not bloat HaveBox with features. HaveBox 2.0.0 now consist of a core with the basic features build in. Auxiliary features like scanners, config injection or xml configuration, will be added via sub-configs. Sub-config is the key word to extend HaveBox from now on. It should now be possible for everybody, to write a sub-config to customize HaveBox.

The Breaking Changes


Scanners

I have removed the scanner concept from config. I deprecated scanners in version 1.6.0, and from now on, scanner has to be defined sub-configs. HaveBox still comes with a scanner called SimpleScanner, but now it is a sub-config which have to be merged in to the config. See more in the documentation: HaveBox Scanners

Config injection

Config injection has to be enabled by merging in the Config Injection sub-config into the config.  See more in the documentation: Config Injection

Spawning Child Containers

The Spawn methods has been removed. Now you have to configure the life-time, of the singletons in the config section and call CreateChildContainer to create a child container. In this way, it is possible to combine the functionality of the spawn methods. See more in the documentation: Custom life-times

The New Features


TryGetInstance

It now possible to try-getting an instance. It is the same try-get functionality known from the rest of the .NET frameworks. If it succeeds the method returns true, and there will be an instance in the out parameter, else it return false, and there will be NULL in the out parameter.

How About Performance?


HaveBox 2.0.0 has also been optimized for performance. The ilasm has been cleaned and reduced, plus I have written a hashtable to replace Dictionary. The new hashtable is almost twice as fast compared to Dictionary(which also is a hashtable, but less optimal written, check the .NET reference sources.).

The concept app, is showing some nice improvement in performance, but I urge you download HaveBox and do your own testing.

That's all for now


HaveBox 2.0.0 can be downloaded from Nuget: http://www.nuget.org/packages/HaveBox/
The project page: https://bitbucket.org/Have/havebox/downloads

And don't forget to checkout HaveBoxJSON and HaveBoxStates.

Enjoy