Dienstag, 3. Dezember 2013

Get all changesets contained in a merge operation

When merging changes from one TFS branch to another, you can select to merge all changes up to a specific Version, or you can perform a chery pick merge. The latter means, that you pick the changesets you want to merge manually, which allows you to pick a not coherent sequence of changesets for merge.

If you want to know, given a changeset number representing a changeset that contains merges, changes from which changesets are included, afaik you need to aks the TFS API. To make life easier for you, here is my solution:


var tfs = new TfsTeamProjectCollection(new Uri("http://yourServer:8080/tfs/DefaultCollection"));
tfs.EnsureAuthenticated();
var versionControl = tfs.GetService<VersionControlServer>();

var changeSet = versionControl.GetChangeset(3894);
var mergeParentChangesets = changeSet.Changes
                                        .SelectMany(c => versionControl.QueryMergeRelationships(c.Item.ServerItem))
                                        .Select(i => i.Version)
                                        .Cast<ChangesetVersionSpec>()
                                        .Select(i => i.ChangesetId)
                                        .Distinct();


Here my changeset number is 3894. I iterate over all the changes in the changeset, asking for the merge relationships of each Change. I have to use SelectMany as QueryMergeRelationships returns an array of VersionSpec instances. Indeed, all these instances are truely ChangesetsVersionSpec objects, hence the cast. The latter object exposes the changeset id that we can collect in a distinct list.

Hope this helps, and happy merging!

Dienstag, 1. Oktober 2013

BASTA 2013 Follow Up

Auf der diesjährigen BASTA durfte ich unter dem Titel "Talk to my TFS" zum Thema TFS-API sprechen.

Folien und Demos zum Vortrag stehen jetzt zum download bereit.

Fragen und Kommentare zum Vortrag nehme ich gerne entgegen!

Viel Spaß mit dem Demos und dem TFS!

Donnerstag, 22. August 2013

Getting WebDeploy to work with Team Build with VS2012 & TFS2012

Lately I could finally make WebDeploy work from our Team build, deploying a WebSite that uses EF Code first as a database.

There is a lot of confusing stuff out there regarding this issue, and it took me some time to put all the pieces together to make it finally work.

That's why I am adding my own five Cents to it, as well as for having a reference if I ever have to do this again.

My Setup

Before going into detail on my solution, here is my Setup:
  • Two VS 2012 web-Solutions: one MVC WebApi Hosting a Service layer, and one vanilla ASP.NET Website using AngularJs for the Client. The former one was using an EF Code first model to store it's data and to run queries.
  • A Team build to be performed on an TFS 2012 Server, the build Agent running on the target web Server.
  • A web Server running IIS7 on a Windows Server 2012 machine

Install WebDeploy

The first step is to install WebDeploy on the target Server. On the web you find that using WebDeploy is different on IIS6 and IIS7 (Tory Hunts bolg entry was a good reference for that). IIS6 uses the "Web Deployment Agent Service" while IIS7 uses "Web Management Service".

It turned out, that with VS2012 you can use either way if you have IIS7 as in my case. I could not get the Web Management Service method to work, so I got along with Web Deployment Agent Service, which requieres a Admin-User to do the deployment. Due to the fact that the target Server was on our own Network, this was not a Problem for me.

The easiest way to install web deploy is using the Web Platform Installer. Under the Products-Tab search for web deploy and install "Web Deploy 3.5".



Installing Web Deploy using WebPI
The installer should configure the Firewall accordingly by adding a rule called "WdeployAgent" allowing incoming Connections on TCP Port 80. It also started the "Webbereitstellungs-Agent-Dienst" for me, which according to web sources you should not take for granted - so better double check.

Deploying a solution from Visual Studio

Next I tried to deploy a solution using Visual Studio. To do that, you need to create the target Website on the IIS of the target Server. I created a new Website that contains two applications: api and Client, one for the MVC WebApi Project and one for the Client.
IIS configuration on the target IIS
I started to deploy the Client Project, as it needed no database and so I thought it was easier to do. To publish a Project using VS2012 right-click the Project node and select "Publish". This fires up a Dialog that was different to all descriptions I found on the web, because they mostly referred to VS2010. On MSDN there is a nice Explanation of all the Settings that can be made.

You can create multiple publish profiles there. The most important Settings site is the "Connection"-Tab. The publish method of choice is "Web Deploy", which means you want to use either the Agent Service or the Management Serivce. Which one is acutally choosen depends on the Service Url you enter. According to MSDN, if you use http://machineName , the Agent Service is used. If your URL starts with https it should use the Management Service - but as I said, I could not get this one to work for me.
As Site/application I specified to use the IIS site and application that I have formerly created. The UserName / Password must be the built-in local Administrator account of the deployment machine (or a Domain admin account, which did not work for me). It is documented that a different user that has Administrator privileges will NOT work. If you tick the Save Password box, the Password will be saved encrypted in an local Settings file.
Visual Studio Deployment Settings
If you hit Validate Connection and everything is properly configured, you should get a green tickmark indicating that the Connection to the Agent Service can be established. Otherwise you get a more or less cryptic error message which are more or less well documented.
If you get the green tickmark, you can rush through the next steps of the wizzard without any further Action, or you just hit Publish. This Triggers a VS build and should publish your solution to the target server.

The Information you entered to the wizzard are being stored in your Project in the Properties Folder. There is a Sub Folder named PublishProfiles that contains a .pubxml File for each Profile. Alongside, but not shown in VS by Default, is a .pubxml.user file for each Profile, which contains the encrypted Password, in case you ticked the Save Password box. We Need to Change the .pubxml file later on, so it is good to know where it resides.

Integration with Team build

So far, this was quite easy and I was in a good mood to just integrate this with my Team build. To do this, you first Need to Setup a Team build for your solution. I skip that part here, as it is not the scope of this post. Given you have a Team build, you Need to tell it that it should deploy your solution(s). On the web you find the solution to add bunch of MSBuild-Parameters at the Process-Tab of the build Definition. This seemed to be messy to me, and you are totally lost if you want to publish more than one Project in one build.
I wanted to use the publish Profile I formerly created to be used by my Team build. That way I don't Need to maintain the Information more than once. After crawling the web for a while Scott Hanselmans blog post put me back on track: you can specify a PublishProfile Parameter for MSBuild to tell it to use the .pubxml-File. For being able to publish multiple Websites, you must not pass this as a Parameter to MSBuild using the build Definition, but you must incorporate the Switches in the .csproj file.
To do so, right click the Project and select "Unload Project" and then "Edit .csproj" from the context menu. Add the following snippet to the Project file:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DeployOnBuild>True</DeployOnBuild>
    <PublishProfile>pos.client.deploy.pubxml</PublishProfile>
  </PropertyGroup>

The condition ensures, that the Publishing only takes place for release builds. The DeployOnBuild Switch activates the deployment, and the PublishProfile Parameter Points to your publish Settings. So far you will Encounter a "USER_NOT_ADMIN" error from WebDeploy. This is due to the fact, that the .pubxml file does not contain the Password for the supplied Administrator user. This is stored in the .pubxml.user file, which is not added to source control. So in order to make things go right, you must manually edit the .pubxml-File and include the Password. My file Looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <CreatePackageOnPublish>True</CreatePackageOnPublish>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <SiteUrlToLaunchAfterPublish />
    <MSDeployServiceURL>http://machineName</MSDeployServiceURL>
    <DeployIisAppPath>posDeploy/client</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>RemoteAgent</MSDeployPublishMethod>
    <UserName>machineName\administrator</UserName>
    
    <Password>yourSecretPassword</Password>
    
    <PublishDatabaseSettings>
      <Objects xmlns="" />
    </PublishDatabaseSettings>
  </PropertyGroup>
</Project>

The CreatePackageOnPublish-Parameter yields to the creation of a WebDeploy package along with the deployment itself. It is located in the build drop Folder under _PublishedWebsites\YourProject_Package Folder and helps to Keep track of what was acutally published. Please notice the Password-Parameter, that mus contain the Password for the given built-in Administrator account for the deployment machine.

So far, so good...

Up to this Point, you should be able to Queue up your Team build and see your Website published to the target IIS Server.

In the next blog post, I will talk about how to get your EF code first database deployed during the Publishing process.



Donnerstag, 2. Mai 2013

A nice new feature for your ViewModel base class

Back in June 2010 I blogged about a View Model base class for WPF and Silverlight. With slight modifications I still use it today when I have to deal with MVVM.

With .NET 4.5 however, Microsoft added an new feature to the .NET Framework, that can make writing View Models even sweeter: the [CallerMemeberName]-Attribute.

Just a short recall: the view model base class uses two Methods Get and Set to manage property values. In your view model you can write something like

public class MyViewModel : ViewModelBase
{

  public string Name
  {
    get { return Get(() => Name); }
    set { Set(() => Name, value); }
  }

}

This way you get strongly typed properties in your view model, but you get rid of the backing field. And the base class takes care about change notifications via INotifyPropertyChanged. But to many people the lambda expression () => Name was confusing and hard to understand.Would it not be sweet if we could derive the calling property name from the context?

This was possible ever since by using the StackFrame class like this:

var stackTrace = new StackTrace();
var frame = stackTrace.GetFrame(1);
var callerName = frame.GetMethod().Name;

But this approach seems a bit cumbersome and has performance penalties, becuase building up the stack trace is an expensive operation. And for a property setter the the delivered method name is like "set_propertyName" - so additional work is needed to fiddle out the pure method name.

Thing get more handy with the new [CallerMemeberName] attribute. You can place it on a methods string parameter and this parameter will be filled with the name of the caller. Bummer. So your OnPropertyChanged-Method can look like this:

protected void RaiseNotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
  if (PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

This can be incorporated easily in our view model base class. It will look like this (a lot of stuff is ommited for brevity):

public class ViewModelBase : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

  private Dictionary<string, object> _value = new Dictionary<string, object>(); 

  protected T Get<T>([CallerMemberName] string callerMemberName = "")
  {
    if (!_value.ContainsKey(callerMemberName))
      return default(T);

    return (T)_value[callerMemberName];
  }

  protected void Set<T>(T value, [CallerMemberName] string callerMemberName = "")
  {
    if (!_value.ContainsKey(callerMemberName))
      _value.Add(callerMemberName, value);

      _value[callerMemberName] = value;

    RaiseNotifyPropertyChanged(callerMemberName);
  }

  protected virtual void RaiseNotifyPropertyChanged(string propertyName)
  {
    if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  }
}

We still have our methods Get / Set around, but they get an additional optional parameter for the caller member name. With this at hand, our above property example looks like this:

public class MyViewModel : ViewModelBase
{

  public string Name
  {
    get { return Get<string>(); }
    set { Set(value); }
  }

}

The one thing to do now, is explicitly stating the return type in the Get()-Method, because it can no longer be derived from the lambda expression. But you never get anything for free, right? Another downside is, that the attribute is not available in Silverlight.

It's a kind of magic - impress your colleagues with this one :-)


Mittwoch, 17. April 2013

Sharepoint Item Level Permissions via List Settings in C#

A forum post made me aware of the possibility to set item level permissions for a sharepoint list in a configurative way, without the need of writing an event receiver. Just jump to your list and navigate to

[Ribbon Region] List Tools -> [Tab] List -> [Group] Settings -> [Button] List Settings

On the list settings page select

[Region] General Settings -> [Link] Advanced settings -> [Region] Item-Level Permissions

You should see something like this:


This is great because it enables me to do a lot of the stuff I have done with event revievers before, so it saves me a lot of code.

But of course I want to set these in code, for being able to deploy my development by menas of an wsp-file. Say I want to configure the list in a way that a user can only see and edit the items he created. I was browsing thorugh the properties of the SPList-object and found something that seems a little bit like a hack to me, but here is the way it goes:

SPList myList = GetMyList();
myList.ReadSecurity = 2;
myList.WriteSecurity = 2;
myList.Update();


Yeah, belive it or not, those two are integer fields. According to MSDN we can set the following values for ReadSecurity:
  • 1 - All users have Read access to all items. 
  • 2 - Users have Read access only to items that they create. 
For WriteSecurity the following values are allowed:
  • 1 — All users can modify all items.
  • 2 — Users can modify only items that they create.
  • 4 — Users cannot modify any list item.
The programming model for this is really ugly, but it serves the need. This applies to Sharepoint 2010 where I tested it, and according to MSDN it is the same for shapreoint 2013.

Enjoy!


Dienstag, 19. Februar 2013

TFS 2012 API - Get all work items assigned to a user

Just playing around with TFS API. I always have to remeber how to start, so I document my findings here, as a reference for me - and maybe it might help someone else...

So if you want to query all WorkItems assigned the current user you first have to reference

  • Microsoft.TeamFoundation.Client
  • Microsoft.TeamFoundation.Common
  • Microsoft.TeamFoundation.WorkItemTracking.Client
Then use the following code:

var collection = new TfsTeamProjectCollection(new Uri("http://nb-tri:8080/tfs/defaultcollection"));
collection.EnsureAuthenticated();

var query =
    "SELECT * " +
    "FROM WorkItems " +
    "WHERE [System.TeamProject] = @project and " +
    "      [System.WorkItemType] <> '' and " +
    "      [System.State] <> '' and " +
    "      [System.AssignedTo] = @user " +
    "ORDER BY [System.Id] ";

var wiStore = collection.GetService<WorkItemStore>();
var parameter = new Dictionary<string, string>
    {
        {"project", "ScrumTest"},
        {"user", collection.AuthorizedIdentity.DisplayName}
    };
var result = wiStore.Query(query, parameter);


That's it... easy, isn't it?


Donnerstag, 7. Februar 2013

Playing around with ZeroMq

Today I was playing around with ZeroMq. I found a nice introduction on the topic for the latest version. In addition to what is written there, here are my findings.

General ZeroMq

ZeroMq is a library based on socket communication. The big advantage in contrast to plain socket programming is, that ZeroMq uses internal queues and enables various message patterns by default while hiding the details.
A central concept in ZeroMq is, surprisingly, the socket. Sockets have a certain type and are usually used in pairs - each pair enables a common communication pattern as:
  • Publish / Subscribe (PUB / SUB)
  • Request / Response (REQ / REP)
  • Push / Pull (PUSH / PULL)
The server, or more generally the most stable peer, opens a socket and binds to it. During the bind an address, aka endpoint, is given to the socket. Multiple other peers can then connect to this socket using the opposite socket type. I. e. for Request / Response the server binds to a REP socket on a certain address and the client connects via an REQ socket to the given address.

The following transport types are supported:





  • inproc
local in-process (inter-thread) communication transport
  • ipc
local inter-process communication transport
  • tcp
unicast transport using TCP
  • pgmepgm
reliable multicast transport using PGM
As you can see, communication is limited to intranet bindings, so there is no way to communicate via http.

As ZeroMq uses internal queues it is generally not important wether a socket is already bound before a client connects or if a client is connected prior to binding a socket. But one address can only be bound to one peer at a time - another binding yields an exception.

Basically all messages are represented as simple plain strings.

Getting Started

I will discuess the most common communication patterns in the following sections. To get started, kick off a new VS Solution and get the clrzmq package using nuget.


Make sure to select "Include prerelease" to get the latest version.

The general usage pattern of the ZeroMq API is always as follows:

  • Creating a ZeroMq Context class by using var ctx = ZmqContext.Create()
  • Create a socket using the context instance by calling var socket = ctx.CreateSocket(socketType)
  • Bind / connect to the socket with a given address by calling socket.Bind("tcp://127.0.0.1:5000") or socket.Connect("tcp://127.0.0.1:5000")
  • Sending / Recieving messages by calling socket.Send(message, encoding) or socket.Receive(encoding)
The following snippet ilustrates this basic protocol:


using (var context = ZmqContext.Create())
{
    using (var socket = context.CreateSocket(SocketType.REQ))
    {
        socket.Connect("tcp://127.0.0.1:5000"); - OR - socket.Bind("tcp://127.0.0.1:5000");

        socket.Send("Hello", Encoding.UTF8); - OR - var msg = socket.Receive(Encoding.UTF8);
    }
}

Request / Response

The server binds to a REP typed socket, the clients connect using a REQ socket. Here is the server code:

using (var context = ZmqContext.Create())
{
    using (var socket = context.CreateSocket(SocketType.REP))
    {
        socket.Bind("tcp://127.0.0.1:5000");
        while (true)
        {
            var recievedMessage = socket.Receive(Encoding.UTF8);
            Console.WriteLine("Recieved message: '{0}'", recievedMessage);
            var replyMessage = String.Format("This is the reply to message '{0}'", recievedMessage);
            Console.WriteLine("Sending reply: '{0}'", replyMessage);
            socket.Send(replyMessage, Encoding.UTF8);
        }
    }
}

The client looks like this:

using (var context = ZmqContext.Create())
{
                
    using (var socket = context.CreateSocket(SocketType.REQ))
    {
        socket.Connect("tcp://127.0.0.1:5000");
        while (true)
        {
            Console.WriteLine("\nEnter message (Enter to quit)");
            var sendMessage = Console.ReadLine();

            if (String.IsNullOrEmpty(sendMessage))
                return;

            Console.WriteLine("Sending message '{0}'", sendMessage);
            socket.Send(sendMessage, Encoding.UTF8);
            var replyMesssage = socket.Receive(Encoding.UTF8);
            Console.WriteLine("Recieved reply message '{0}'", replyMesssage);
        }
    }
}

My findings with Request / Response:

  • For the client does not matter wether the service is up and running when the client starts. 
  • The client blocks at send until the server is present (a timeout can be specified).
  • There is no way of finding out wether the server is present or if at least on client is connected, expect waiting for the timeout to expire.
  • Request and response must come in pairs. To subsequent request fail as well as the response is mandatory.

Push / Pull

This pattern is named Pipeline in the documentation and they use it in a way that there is a source of messages that equally distributes these among all connected peers. The peers do some processing and then sending the results to a third party which is the message sink. The worker peers use two sockets, one to receive messages from the source and one to send messages to the sink. For my personal testing I have chosen an easiser setup with a pushing sender an a pulling receiver.

The server:

private static void Push()
{
    int messageNumber = 0;
    using (var ctx = ZmqContext.Create())
    {
        using (var socket = ctx.CreateSocket(SocketType.PUSH))
        {
            socket.Bind("tcp://127.0.0.1:5000");

            while (true)
            {
                var msg = String.Format("{0}: pushing message {1}", DateTime.Now, messageNumber++);
                Console.WriteLine("Pushing: " + msg);
                socket.Send(msg, Encoding.UTF8);
                Thread.Sleep(1000);
            }
        }
    }
}

And the client:

private static void Push()
{
    int messageNumber = 0;
    using (var ctx = ZmqContext.Create())
    {
        using (var socket = ctx.CreateSocket(SocketType.PUSH))
        {
            socket.Bind("tcp://127.0.0.1:5000");

            while (true)
            {
                var msg = String.Format("{0}: pushing message {1}", DateTime.Now, messageNumber++);
                Console.WriteLine("Pushing: " + msg);
                socket.Send(msg, Encoding.UTF8);
                Thread.Sleep(1000);
            }
        }
    }
}

My findings with Push / Pull


  • Sending on a PUSH socket blocks until at least one pulling client is present (a timeout can be defined).
  • Messages are distributed round-robin to connected peers.
  • As only a single bind to an endpoint is allowed, only one process cann push at a time. 
  • Connecting to a PUSH socket and then sending message yields to lost messages.

Publish / Subscribe

The server binds a PUB socket, the client subscribes via SUB. In contrast to the previous examples the client does not use the Connect method, but the Subscribe / SubscribeAll method. When using Subscribe the client can pass a list of message prefixes it is interested in.

Here goes the server:

private static void Pub(IEnumerable<String> prefixes)
{
    if (prefixes.Count() == 0)
        prefixes = new[] { "Apple", "Microsoft", "Google" };

    var prefixMessageCounter = new Dictionary<String, int>();

    foreach (var prefix in prefixes)
    {
        prefixMessageCounter.Add(prefix, 0);
    }

    using (var ctx = ZmqContext.Create())
    {
        using (var socket = ctx.CreateSocket(SocketType.PUB))
        {
            socket.Bind("tcp://127.0.0.1:5000");

            while (true)
            {
                foreach (var prefix in prefixes)
                {
                    var msg = String.Format("{0}: Message number {1}", prefix, prefixMessageCounter[prefix]++);
                    Console.WriteLine("Publishing: " + msg);
                    socket.Send(msg, Encoding.UTF8);
                    Thread.Sleep(1000);
                }

            }
        }
    }
}

And the client:

private static void Sub(IEnumerable<String> prefixes)
{
    using (var ctx = ZmqContext.Create())
    {
        using (var socket = ctx.CreateSocket(SocketType.SUB))
        {
            if (prefixes.Count() == 0)
                socket.SubscribeAll();
            else
                foreach (var prefix in prefixes)
                    socket.Subscribe(Encoding.UTF8.GetBytes(prefix));

            socket.Connect("tcp://127.0.0.1:5000");

            while (true)
            {
                var msg = socket.Receive(Encoding.UTF8);
                Console.WriteLine("Received: " + msg);
                Thread.Sleep(1000);
            }
        }
    }
}

My findings with Publish / Subscribe

  • If no subscriber is listening the message will get lost.
  • All the subscribers will get all published messages.
  • There is no way to see if someone is subscribed.
  • As only a single bind to an endpoint is allowed, only one process cann publish at a time.
  • Connecting to a PUB socket yields no error but has no effect either.

Some "limitations" and the conclusion

While trying around with ZeroMq a few questions popped out in my mind, and I looked for answers on the web. Finally I came up with the following findings, which may be limitations in some cases:
  • No http communication
  • No way of getting a peers IP-Address on connect
  • No way of seeing if a port is bound or if anyone is connected
Of course all these points have a rationale, which I understand. I write down these points to make it easier to see in which cases using ZeroMq might not be an option: namely if one of the points above is a requirement for you.

On the other hand, when you have the need to quickly implement messaging using a well defined communication pattern, ZeroMq is great. The code is very easy as you can see above. And it is blazing fast. Furthermore there are a lot advanced communication patterns that I have not covered. Consult the ZeroMq documentation for this.

socket.send("Have fun with ZeroMq!", Encoding.UTF8);