TFS Reporting

I recently got tasked with setting up reporting on our TFS server, when doing so i came across this rather annoying issue when attempting to connect to our warehouse 'tfs_warehouse' and our analysis services 'tfs_analysis' databases.

The error i received when connecting to the exisitng database was:

The database you specified cannot be used. the database exists but it's schema is not valid for use with Team Foundation Server.

We upgraded our TFS server from 2010 to 2012, in doing this the schema on both these tables didn't get upgraded to work with TFS2012 & reporting services.

The following article explains how to resolve this issue and re-create both the warehouse and analysis OLAP databse:

http://social.technet.microsoft.com/wiki/contents/articles/20113.rebuild-tfs-warehouse-and-analysis-databases-from-scratch.aspx

Following the article wasn't a precise art for me, firstly, I managed to get the databases to create straight away without error.

After this, navigating to the localhost to in order to access the warehousecontrolservice.asmx didn't work for me.

I needed to provide the named instance of the TFS server so:

http://<SERVERNAME>:8080/tfs/teamfoundation/administration/v3.0/warehousecontrolservice.asmx

 Instead of

http://localhost:8080/VirtualDirectory/TeamFoundation/Administration/v3.0/WarehouseControlService.asmx

When i tried to process the Analysis cube the config returned with an error

Reporting for Team Foundation Server cannot execute job Incremental Analysis Database Sync for TEAM FOUNDATION because the Analysis Services processing is offline. Use the Team Foundation Administration Console to start reporting

In order to get around this error, i opened the SQL 2012 TFS instance with the connection set to 'Analysis Services' I then right clicked on the tfs_analysis database and selected 'process'.

Once i had run the process; i had to import the reports as described in the following blog post:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/1d566b21-3082-4aa8-bbc8-d02fb76791de/tfs-2010-reporting-problem-reports-data-missing-urgent?forum=tfsreporting

After the reports displayed, trying to run them proved problematic, the final change i had to make was to update the datasources in each report.

The Error i encountered was:

  • The report server cannot process the report or shared dataset. The shared data source 'TfsReportDS' for the report server or SharePoint site is not valid. Browse to the server or site and select a shared data source. (rsInvalidDataSourceRefere
  •  
  •  
  • sfnce)
In order to get rid of this error, I clicked on the menu on each report and selected 'Edit In Report Builder'.

In the report builder, in the left hand 'Report Data' folder structure, I expanded the 'Data Sources' folder and then right clicked each of the data sources and selected 'Data Source Properties', I then browsed to my connections for both the ReportDS and OLAPReportDS and selected the respective connection.

Once both connections are set the report should display.

VS2012 Build Server unable to create the workspace due to mapping conflict

I encountered this error message today and went around the houses looking for solutions to my problem:

Exception Message: Unable to create the workspace due to a mapping conflict. You may need to manually delete an old workspace. You can get a list of workspaces on a computer with the command 'tf workspaces /computer

I got the issue by deleting a broken build on our build server and then trying to recreate the build with the same settings in visual studio 2012.

It appears that the Network Service holds on to the mappings of the orginal build under the workspace it created for this.

In order to solve this i had to delete the original workspace from the network service using the following command:

C:\Program Files (x86)\Microsoft Visual Studio 11.0>TF workspace /delete /collec
tion:http://<YOURSERVERNAME>:8080/tfs/defaultcollection <WORKSPACENAME>;"NT AUTHORITY\NETWORK SERVICE"

The workspace name is displayed in the error messgae when you attempt the new build and it fails, it will be something along the lines of 7_1_<YOURSERVERNAME>.

You can also get this information using the TF workspaces command as suggested in the exception message.

Dependency Injection


Dependency injection can be used to satisfy what’s known as the dependency inversion principle.

According to Wikipedia:

In object oriented programming, the dependency inversion principle refers to a specific form of decoupling where conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed) for the purpose of rendering high-level modules independent of the low-level module implementation details. 

The principle states:

A. High-level modules should not depend on low-level modules. Both should depend on abstractions. 
B. Abstractions should not depend upon details. Details should depend upon abstractions.

What this means in real terms is that the higher level layers, for example, the business logic layer, should be able to exist independently of the low level layers i.e. presentation. 

If we take an MVC application as an example, we may split our application logic into a separate high level business layer; this then allows our MVC application to deal with the serving of the views at the lower level.

If our high level business layer is aware of our low level presentation layer then it renders our higher level business layer unusable with any other application front end; it’s too closely coupled to the MVC low level presentation layer.

Alternatively, if we make our MVC application reference the high level business layer classes directly, this frees up our high level business layer to be used with other applications, but, leaves the tight coupling on the front end. Our low level presentation layer can’t exist peacefully without our current business logic implementation.

In order to solve this problem we need to create a level of abstraction; we do this by defining interfaces at the higher business logic level that expose the services required.

Our low level presentation layer must now depend upon the high level business logic layer in order to use the interfaces to call out to the application logic. 

In real terms any low level layer adds a reference to the higher level project and utilises the interfaces as a contract to access the exposed services.

Example

In order to demonstrate this concept, we can create a simple MVC4 example application. 
The application consists of:
  • High level business logic layer - ‘DependencyInjection.BusinessLayer’
  • Low level unit testing layer - ‘DependencyInjection.Tests
  • Low level presentation layer - ‘DependencyInjection.WebClient’



We create the business layer first, inside the business layer we generate a simple class to handle the number of cookies that the cookie monster has currently in his possession.

Our cookie manager class looks something like this:



The cookie manager class implements an interface called ICookieManager, in order to create this interface in VS2012, right click on the CookieManager class declaration and select Refactor and then Extract Interface (Alternatively you add and write your own).

This will generate an interface that looks something like this:



All we then need to do on this layer is ensure our interface is public and build the application.

Ok, so now we have our interface and class, we need to add a reference to the business layer from our presentation layer.

Once we've done that; inside the presentation layer we can create a controller that looks something like this:


To do this we bring in a reference to the high level business layer:



 using DependencyInjection.BusinessLayer;

Then create a member variable of type ICookieManager, we create a constructor that takes as a parameter an object of type ICookieManager. 

Our controller is now loosely coupled to our business layer implementation; all the controller class expecting is an interface contract of type ICookieManager as a parameter.

When it comes to writing our unit tests we can use the interface to pass the dependency through to the controller.


Our unit test looks something like this:



You can see the cookie manager type is injected directly into the controller and our unit test passes by returning the correct number of cookies from the controller.

At this stage we can also incorporate a mocking framework and create a mock object that is of type ICookieManager, this will allow us to test the controller in isolation of the service layer and is where dependency injection really comes into its own.

Great, so we’ve called our controller and it’s returned the number of cookies.

So what happens when we run our application?


Well, when we run our application we get the following error:



It states that the application has no parameterless constructor defined for the object. 

Which is correct, we want the application to force the user to inject the dependency into the controller to ensure that we are working strictly from the abstract interface. 

In order for the application to know what object type to pass to the constructor we need to implement a dependency injection (DI) framework to tell the application what type of object to map to the interface.

There are a lot of DI frameworks available online; we chose Ninject.

Ninject

We can download Ninject from the package manager in VS2012 by going to Tools expand Library Package Manager and then click Package Manager Console.
You can use the following Nuget command to install the Ninject application:

Install-Package Ninject.MVC3 -Version 3.0.0.6 

If the application installs correctly we can see a new class in the App_Start folder called NinjectWebCommon.cs.

If we open this class and take a look inside; we can see the associated methods required for the Ninject framework to operate.

In order to add our CookieManager class to the Ninject service register we need to add a reference to our business layer in this class by adding the line of code:



    using DependencyInjection.BusinessLayer;

We then need to register the class we created by adding a binding in to the RegisterServices Class.


Once this binding is added and we run the application, the correct view for the controller should display. 

So that concludes this post on dependency injection; In my next post i'll take a look at how to use a mocking framework to implement your interface on a mock service and test your controller in complete isolation.

Setting Up StyleCop For VS2012 Agile Team

StyleCop 

StyleCop is a visual studio add-in that allows us to apply coding guidelines to our projects, if we want our code to look a certain way then StyleCop can help us to enforce these guidelines through warning or errors.  



StyleCop can be downloaded from the following location: http://stylecop.codeplex.com/  

In order for us to utilise StyleCop, we have two options; install the StyleCop executable, or, for more collaborative development situations, set up StyleCop against the project and allow each member of the team to link to the target values.  


Install Style Cop 

StyleCop should initially be installed on a single development machine, once the application has been installed then the user can open the project they wish to apply some coding guidelines to. 
 If we right click on our project the context menu should now contain an option to for StyleCop Settings. 


Context menu with StyleCop settings

If we click this we get the StyleCop settings form, this allows us to define what our guidelines are for this project. 


StyleCop Settings Form

The image above shows the StyleCop settings with maintainability, Layout and Naming rules all checked for inclusion. 

Once we’ve chosen our settings for this project we can apply them to all of the projects in the solution by locating the settings.stylecop file in the root folder of the project we applied the settings to. Copy this file into the root folder of the solution. 

Inside the solution we need to open the StyleCop settings for each project and ensure that the setting Merge with settings file found in parent folders is selected. 

This will enforce any StyleCop settings higher up in the folder structure. 

StyleCop Settings Files Tab

Attempt to build the application and you should receive warnings for any code that breaks your selected guidelines.

StyleCop rules being violated (errors flag set to true)
This gives us an overview of how set up StyleCop on a single machine, but what if we want to set up StyleCop in a team environment?  

There’s at least two requirements that we might need to satisfy, the first is setting up style cop on each developers machine, the second is setting up StyleCop on an integrated build machine.

Setting up StyleCop on multiple machines 

StyleCop team integration doesn’t require each user to install the StyleCop client; in fact, we can set StyleCop up with a few easy steps using files from the original install. 

Firstly, we need to locate the StyleCop targets file, this can be found in the location: {Program Files}\MSBuild\StyleCop\v4.x 

Copy and paste the file StyleCop.Targets into the root folder of the solution we want to apply the guidelines to.  

Next, create a folder called StyleCop in the root folder of the solution, then, Locate the folder {Program Files}/StyleCop 4.x, copy and paste all files from this folder to the new StyleCop folder you created in the solution root folder. 


Adding files to the solution 

In visual studio add the StyleCop.Targets file by right clicking on the solution, selecting Add and then Existing Item. 

In visual studio add the settings.stylecop file we created in the install StyleCop section of this walkthrough by right clicking on the solution, selecting Add and then Existing Item. 

The previous actions should create a folder called Solution Items by default. 

Right click on the folder Solution Items, select Add, and select New Solution Folder. 

Give the folder the name StyleCop. 

Right click on the StyleCop folder and select Add and then Existing Item. 

Navigate to the StyleCop folder you created in the root folder of the solution and add all of the files in this folder to the solution folder in visual studio. 

When you’ve added both of these files and the folder your solution should look something like this: 

Solution Items

Editing StyleCop.Targets 

 Open the StyleCop.Targets file; locate the UsingTask element at the top of the file and replace it with the following element:


<UsingTask AssemblyFile="$(SolutionDir)\StyleCop\StyleCop.dll" TaskName="StyleCopTask"/>

 
StyleCop Targets UsingTask


Editing the project files 
Open the solution folder in windows explorer and select the first project that we want to add StyleCop settings to and find the .csproj file, ensure the file is checked out and then right click and open the file in a text editor.  

Inside the text editor we need to add an import statement to the project file  
<Import Project="$(StyleCopTargets)" /> 

You can add this in under other import files in the project or directly underneath the following import file that should already exist: 
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 

Repeat this for each project in the solution that you want the guidelines applied to. 
Check in the solution. 

Creating The Environment Variable 

We need to now link the StyleCop on each developers machine, go to each machine and get latest on the project that was just edited then follow the next steps on each user machine: 

Create an environment variable that allows the other development machines to see where the StyleCop.Targets file is located. 

To create an environment variable in the start menu type run, select enter, and then enter the command sysdm.cpl in the run menu, press enter and then select the button Environment Variables.
  
Add Environmental Variable



In the System Variables section, select Add and create an environment variable called StyleCopTargetsin the value field we need add in the location of the StyleCop.Targets file that exists in the solution. 

Select ok to create this variable and then restart the machine 

Once the machine has restarted open the solution and check that the project can be built. If it’s a new solution then try adding in some code that you know breaks the style guidelines, attempt to build and ensure that you receive warnings for any guidelines you’ve broken. 


StyleCop on the Build Server 

If the project team is utilising continuous build integration and you want to set StyleCop up on the build server then you can just repeat the steps above or install the application directly to the server. 

In either case you still need to create the environment variable. 

If you choose to not install the application then you will need to copy  the StyleCop folder, StyleCop.Targets and settings.stylecop files to a location on the server, the environment variable should point to the location of the StyleCop.Targets file on the build server and the UsingTask Should point to the location of the StyleCop.dll file on the build server. 

Make sure you restart the server in order for it to recognise the Environment variables. 


Warnings Vs. errors 

Out of the box, StyleCop sets warnings for any style guidelines that have been violated, we may wish to change this to errors and we can do so by setting a second environment variable.  

The details for the environment variable are outlined below: 

NameStyleCopTreatErrorsAsWarnings 
Value: False 

Again you need to restart to get any environment variable to register on either a server or dev machine.