Creating TFS-scheduled jobs

As TFS runs in the background, there is always a requirement to run scheduled jobs that perform a batch operation silently in the background. The TFS Background Job Agent is used to run certain tasks that can be hooked into the TFS system and that run automatically when scheduled.

Getting ready

Before getting started, create a library class and name it ScheduledJobs. We need to add a reference to the following files:

  • Microsoft.TeamFoundation.Framework.Server.dll located at C:Program FilesMicrosoft Team Foundation Server 12.0Application TierWeb ServicesBin
  • Microsoft.TeamFoundation.Common.dll located at C:Program Files (x86)Microsoft Visual Studio 12.0Common7IDEReferenceAssembliesv2.0
  • Microsoft.VisualStudio.Services.WebApi.dll located at C:Program Files(x86)Microsoft Visual Studio 12.0Common7IDEReference Assembliesv4.5

Once the setup is ready, let's write the scheduler logic first and later hook it into the TFS system.

We also create a new .NET 4.5 library class called TFS.ScheduledJobs and add a reference to the following files:

  • Microsoft.TeamFoundation.Framework.Server.dll located at C:Program FilesMicrosoft Team Foundation Server 12.0Application TierWeb Servicesin
  • Microsoft. TeamFoundation.Common.dll located at C:Program Files (x86)Microsoft Visual Studio 12.0Common7IDEReferenceAssembliesv2.0
  • Microsoft.VisualStudio.Services.WebApi.dll located at C:Program Files (x86) Microsoft Visual Studio 12.0Common7IDEReferenceAssembliesv4.5

We will be writing the ScheduledJob logic inside the library class and will later hook it to the main job project to run it.

How to do it...

Now let's create ScheduledJob inside TFS using these simple steps:

  1. Create a new class called IdCheckJob and make it inherit variables from ITeamFoundationJobExtension. Then implement the interface. This should now give you the following code:
    using System; 
    using Microsoft.TeamFoundation.Framework.Server; 
    namespace TFS.ScheduledJobs 
    { 
       public class IdCheckJob : ITeamFoundationJobExtension 
       { 
            public TeamFoundationJobExecutionResult Run(TeamFoundationRequestContext requestContext, TeamFoundationJobDefinition jobDefinition,  DateTime queueTime, out 	string resultMessage) 
       { 
          throw new NotImplementedException(); 
       } 
       } 
    }
  2. Now let's implement the Run method, as shown in the following code. The idea is to check every work item and then check which work items have been updated:
    try
    {
      TfsTeamProjectCollection tfsServer = new TfsTeamProjectCollection(GetTFSUri(requestContext));
      WorkItemStore workItemStore = tfsServer.GetService<WorkItemStore>();
    List<WorkItem> changedWorkItems = new List<WorkItem>();
      foreach (WorkItem workItem in workItemStore.Query("SELECT * FROM WorkItems"))
      {
        if (!workItem.Title.StartsWith("#" + workItem.Id + " - "))
        {
          workItem.Title = "#" + workItem.Id + " - " + workItem.Title;
          changedWorkItems.Add(workItem);
        }
      }
      if (changedWorkItems.Count > 0)
      {
         workItemStore.BatchSave(changedWorkItems.ToArray());
         resultMessage = changedWorkItems.Count + " work item titles updated.";
       }
       else
       {
         resultMessage = "no work item titles to update.";
       }
     return TeamFoundationJobExecutionResult.Succeeded;
    }
    catch (Exception ex)
    {
       resultMessage = "Job Failed: " + ex.ToString();
       EventLog.WriteEntry("TFS Service", resultMessage,EventLogEntryType.Error);
       return TeamFoundationJobExecutionResult.Failed;
    }

    The code selects the updated work items and updates the database with a message.

    You can see that the resultMessage variable is also updated so that we can see the job history.

  3. Now compile the project and place the .dll and .pdb files in C:Program FilesMicrosoft Team Foundation Server 12.0Application TierTFSJobAgentPlugins.
  4. Once the file has been successfully placed, we need to register the TFS job. To register the job, we simply write a console application and run the following code:
    var tfsUri = new Uri("http://localhost:8080/tfs");
    var config = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
    var jobService =  config.GetService<ITeamFoundationJobService>();
    var jobDefinition = new TeamFoundationJobDefinition("Check WorkItem Job", "TFS.ScheduledJobs.IdCheckJob");
    jobDefinition.EnabledState = TeamFoundationJobEnabledState.Enabled;
    jobDefinition.Schedule.Add(new TeamFoundationJobSchedule(DateTime.Now,300));
    jobService.UpdateJob(jobDefinition);

    The code will retrieve the job that has been added as a plugin to the TFS job agent and we call UpdateJob to service the plugin.

  5. Once the job is registered, you can verify it using the following SQL statement:
    select * from Tfs_Configuration.dbo.tbl_JobDefinition where JobName = 'Check WorkItem Job'

    If you see an entry that exists in the database, this means the job is running.

  6. You can copy JobId from the data and select JobHistory to verify how the scheduled job is working, as shown in the following code:
    select * from Tfs_Configuration.dbo.tbl_JobHistory WITH (NOLOCK) where JobId = '62FDDA25-4938-4BF7-A7C3- 6A9BF527A20C

    For instance, in my case it gives the appropriate results.

  7. Finally, when you want to stop the scheduled job, you can easily write a console application again to delete the job. Let's take a look at the following code:
    var tfsUri = new Uri("http://localhost:8080/tfs");
    var config = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri); 
    var jobService = config.GetService<ITeamFoundationJobService>(); 
    jobService.DeleteJob(new Guid("62FDDA25-4938-4BF7-A7C3- 6A9BF527A20C"));

Here, you can see that I used the Guid to identify the job rather than using the name. The DeleteJob method will de-register the job from the TFS job agent.

How it works…

TFS is hosted using IIS. There is a specific TFS job agent associated with the TFS, which runs periodically in the background to perform some batch operations. The TFS provides a plugin model to integrate your own scheduled tasks so that when the jobs are being dispatched, it can also run the user code automatically.

Until and unless the job has been deregistered, the TFS automatically picks it up and performs the tasks assigned to it.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.124.145