Заметки консультанта

Шамрай Александр Владимирович

Практическое руководство по отчетности TFS. Настройка OData для трендов

Posted by Шамрай Александр на Январь 14, 2014

<<Содержание

Примечание

Вы можете скачать последнюю версию решения OData, опубликованного Брайаном Келлером, которое можно загрузить здесь. Архив eBook1-Package.zip содержит оригинальную версию OData v2.3 и дополненную версию OData, которая описана в этом документе.

Зачем расширять проект TFS OData?

Существует несколько причин, по которым может потребоваться расширить канал TFS OData, например:

  • Настраиваемые поля рабочих элементов
    Проект TFS OData возвращает только базовый набор полей. Для доступа к вашим настраиваемым полям добавьте их, расширив проект OData.
  • Недостающие данные
    Проект TFS OData предоставляет доступ ко многому, но не все данные обрабатываются в TFS. Если нужно получить доступ к элементу, например, WorkItemHistory или данным связанным с тестами, это можно реализовать как расширение OData.
  • Реализация параметров запросов
    Проект TFS OData поддерживает только ограниченный набор параметров запроса, например, $filter. Для реализации специфического параметра для запроса, например, $expand, нужно расширить проект OData.

В этом руководстве мы добавим канал для всех версий для всех рабочих элементов в командном проекте. Это очень полезно, если вы планируете делать отчеты по тенденции или историческим данным, что мы и планируем сделать в рамках нашего решения.

Выполнение настройки

Примечание

Вы можете найти примеры полного кода в приложении и как часть решения для примера.

Выбор URI

Для нашего решения нам нужно получить доступ ко всем версиям всех рабочих элементов в командном проекте. Мы также должны получить доступ к предварительно рассчитанной таблице Fact для версий рабочего элемента. Для этой цели мы выбрали следующие URI:

Они обеспечивают прямой доступ к WorkItemHistory и предварительно рассчитанной таблице WorkItemFact для выбранного командного проекта.

Добавление к проекту WorkItemHistory и WorkItemFacts

При выполнении запроса проект OData создает экземпляр сущности Project и ищет член WorkItemHistory для возврата. То, что нам нужно сделать, это в дальнейшем добавить этот член в сущность Project.

Данные, которые мы хотим вернуть, — это плоский список всех версий.

  • Перейдите к проекту TFS.OData.Model, откройте папку Entities и откройте файл Project.cs.
  • В класс Project добавьте следующие члены.

    [ForeignProperty]

    public
    IEnumerable<WorkItemRevision> WorkItemHistory { get;
    set; }

    public
    IEnumerable<WorkItemFact> WorkItemFacts { get;
    set; }

Возврат списка WorkItemRevisions и WorkItemFacts

Теперь при выполнении запроса OData будет искать список WorkItemRevisions, нам нужно сделать так, чтобы проект знал о существовании WorkItemRevisions.

  • Перейдите к папке Entities проекта TFS.OData.Model и добавьте новый класс WorkItemRevision. Пример реализации в приложении.
  • Откройте файл TFSData.cs в корневом каталоге проекта TFS.OData.Model и добавьте следующие члены к классу TFSData.

    public
    IQueryable<WorkItemRevision> WorkItemHistory

    {

    get { return CreateQuery<WorkItemRevision>(); }

    }

    public
    IQueryable<WorkItemFact> WorkItemFact

    {

    get { return CreateQuery<WorkItemFact>(); }

    }

  • Вставьте следующий код в метод public override object RepositoryFor(string fullTypeName) класса TFSDAta

    if (fullTypeName == typeof(WorkItemRevision).FullName || fullTypeName == typeof(WorkItemRevision[]).FullName)

    {

    return new WorkItemHistoryRepository(this.tfsProxyFactory.TfsWorkItemHistoryProxy);

    }

    if (fullTypeName == typeof(WorkItemFact).FullName || fullTypeName == typeof(WorkItemFact[]).FullName)

    {

    return new WorkItemFactRepository(this.tfsProxyFactory.TfsWorkItemFactProxy);

    }

  • Откройте файл TfsProxyFactor.cs в папке Serializations проекта TFS.OData.Model и добавьте следующие члены для класса TFSProxyFactory.

    public
    ITfsWorkItemHistoryProxy TfsWorkItemHistoryProxy

    {

    get { return new TFSWorkItemHistoryProxy(this.tfsUri, this.tfsCredentials); }

    }

    public
    ITfsWorkItemFactProxy TfsWorkItemFactProxy

    {

    get { return new TFSWorkItemFactProxy(this.tfsUri, this.tfsCredentials); }

    }

Извлечение WorkItemRevisions

Теперь нам нужно реализовать логику для извлечения WorkItemRevisions.

  • Добавьте следующий интерфейс (желательно поместить его в папку Serializations):

    public
    interface ITfsWorkItemHistoryProxy

    {

    IEnumerable<WorkItemRevision> GetWorkItemHistoryByProject(string projectName, FilterNode rootFilterNode, ODataQueryOperation operation);

    }

  • Добавьте класс TFSWorkItemHistoryProxy в папке Repositories для реализации отношения к классу TFSWorkItemProxy.
  • Добавьте код к методу ExecuteWIQLRequest, который проходит по результату запроса и создает новые экземпляры WorkItemRevision для каждой версии рабочего элемента.

    List<WorkItem> wilist = this.QueryWorkItems(wiql).Cast<WorkItem>() .Skip(operation.SkipCount).Take(operation.TopCount) .Select(w => w).ToArray();

    List<WorkItemRevision> lst = new List<WorkItemRevision>();

    foreach (WorkItem w in wilist) {

    // Get All work item revisions

    foreach (Revision revision in w.Revisions) {

    WorkItemRevision wrkRev = new WorkItemRevision();

    wrkRev.Set(w.ToModel(this.GetTfsWebAccessArtifactUrl(w.Uri)));

    wrkRev.Revision = revision.Index;

    // Get value of fields in the work item revision

    foreach (Field field in w.Fields) {

    wrkRev.SetField(field.Name, revision.Fields[field.Name].Value);

    }

    lst.Add(wrkRev);

    }

    }

Извлечение WorkItemFacts

Теперь нам нужно реализовать логику для извлечения WorkItemFacts.

  • Добавьте следующий интерфейс (желательно поместить его в папку Serializations):

    public
    interface ITfsWorkItemFactProxy

    {

    IEnumerable<WorkItemFact> GetWorkItemFactByProject(string projectName, FilterNode rootFilterNode, ODataQueryOperation operation );

    }

  • Добавьте класс TFSWorkItemFactProxy в папке Repositories для реализации отношения к классу TFSWorkItemProxy.
  • Добавьте код к методу ExecuteWIQLRequest, который пройдет по результату запроса и создаст два новых экземпляра WorkItemFact для каждой версии рабочего элемента, за исключением последней.

    IEnumerable<TeamFoundation.WorkItemTracking.Client.WorkItem> wilist = this.QueryWorkItems(wiql)

    .Cast<TeamFoundation.WorkItemTracking.Client.WorkItem>()

    .Skip(operation.SkipCount).Take(operation.TopCount)

    .Select(w => w).ToArray();

    List<WorkItemFact> lst = new List<WorkItemFact>();

    foreach (TeamFoundation.WorkItemTracking.Client.WorkItem w in wilist)

    {

    TeamFoundation.WorkItemTracking.Client.Revision prevRev=null;

    // Get All work item revisions

    foreach (TeamFoundation.WorkItemTracking.Client.Revision revision in w.Revisions)

    {

    if(prevRev!=null)

    {

    WorkItemFact wiFactPrev = new WorkItemFact();

    wiFactPrev.Project = w.Project.Name;

    wiFactPrev.Id = w.Id;

    wiFactPrev.Revision = (int)prevRev.Fields[«System.Rev»].Value;

    wiFactPrev.RevisionDate = System.Convert.ToDateTime(revision.Fields[ «Changed Date»].Value).Date;

    // Take the date for the next revision

    wiFactPrev.RevisionCount=null;

    wiFactPrev.RecordCount=-1;

    wiFactPrev.SurrogateKey = wiFactPrev.Id + «:» + wiFactPrev.Revision;

    // add numeric values to the fact

    foreach (TeamFoundation.WorkItemTracking.Client.Field field in prevRev.Fields)

    {

    switch (prevRev.Fields[field.Name].FieldDefinition.FieldType)

    {

    case
    TeamFoundation.WorkItemTracking.Client.FieldType.Integer:

    wiFactPrev.SetField(field.Name, System.Convert.ToInt64(field.Value) * -1);

    break;

    case
    TeamFoundation.WorkItemTracking.Client.FieldType.Double:

    wiFactPrev.SetField(field.Name, System.Convert.ToDouble(field.Value) * -1);

    break;

    }

    }

    lst.Add(wiFactPrev);

    }

    prevRev=revision;

    WorkItemFact wiFact = new WorkItemFact();

    wiFact.Project = w.Project.Name;

    wiFact.Id = w.Id;

    wiFact.Revision = (int)revision.Fields[«System.Rev»].Value;

    wiFact.RevisionCount = 1;

    wiFact.RecordCount = 1;

    wiFact.RevisionDate = System.Convert.ToDateTime(revision.Fields[ «Changed Date»].Value).Date;

    wiFact.SurrogateKey = wiFact.Id + «:» + wiFact.Revision;

    // add numeric values to the fact

    foreach (TeamFoundation.WorkItemTracking.Client.Field field in revision.Fields)

    {

    switch (revision.Fields[field.Name].FieldDefinition.FieldType)

    {

    case
    TeamFoundation.WorkItemTracking.Client.FieldType.Integer:

    wiFact.SetField(field.Name, System.Convert.ToInt64(field.Value) );

    break;

    case
    TeamFoundation.WorkItemTracking.Client.FieldType.Double:

    wiFact.SetField(field.Name, System.Convert.ToDouble(field.Value) );

    break;

    }

    }

    lst.Add(wiFact);

    }

    }

    retWorkItems = lst;

Соединяем

Для объединения нам нужно реализовать некоторые соединения OData.

  • Добавьте класс WorkItemRevisionRepositories в папку Repositories реализации IRepository <WorkItemRevision>
  • Добавьте класс WorkItemFactRepositories в папку Repositories реализации IRepository <WorkItemFact>

Нам также необходимо задать правила доступа для наших новых WorkItemRevision и WorkItemFacts. Это выполняется редактированием метода void InitializeService(DataServiceConfiguration config) класса TFSService, который находится в файле TFSService.cs в корневой папке проекта ODataTFS.Web.

Добавьте следующий код:

config.SetEntitySetAccessRule («WorkItemHistory», EntitySetRights.AllRead);

config.SetEntitySetAccessRule («WorkItemFact», EntitySetRights.AllRead);

config.SetEntitySetPageSize («WorkItemHistory», Constants.DefaultEntityPageSize);

config.SetEntitySetPageSize («WorkItemFact», Constants.DefaultEntityPageSize);

Сборка и развертывание

Соберите и установите службы, как описано в разделе Настройка TfsOData.

Тестирование расширения

Теперь вы можете выполнить запрос для получения WorkItemHistory, откройте браузер и перейдите к

http://localhost/DefaultCollection/Projects(‘projectName’)/WorkItemHistory

Примечание

Это только отрывок из всего кода. Свяжитесь с ALM Рейнджерами или Брайаном Келлером, чтобы получить весь код.

Шаги развертывания для настроенного OData Services на IIS

Примечание

Это пошаговое руководство было проверено на Windows Server 2008 R2 Standard SP1, Windows Server 2012 Standard и в Windows Server 2012 R2. Вам может потребоваться адаптировать его в соответствии с вашей средой, если есть какие-либо отличия.
Шаг Описание
1. Перестроить OData для сервера[ ] — Сделано
  • Откройте измененное решение ODataTFS.sln
  • Выберите Build | Rebuild Solution, чтобы удостовериться, что все будет обновлено.
2. Опубликовать web-проект OData на диск[ ] — Сделано
  • Щелкните правой кнопкой мыши на проекте ODataTFS.Web в обозревателе решений и выберите Publish.
  • Вы можете использовать любой метод публикации, который вы хотите, но данная инструкции основывается на методе публикации в файловой системе.

3. Скопировать опубликованный веб-сайт на сервер[ ] — Сделано
  • Скопировать директорий в c:\Inetpub\wwwroot\TfsOdataAlmRangers.
Примечание Если вы выполнили шаги в разделе Настройка TFsOData, пропустите следующие шаги.
  • В IIS менеджере создайте новый веб-сайт.
  • Назовите его tfsodata и свяжите с новым созданным каталогом
  • Убедитесь, что вы используете HTTPS и SSL-сертификат для привязки.
  • Предпочтительно использовать физический путь c:\Inetpub\wwwroot\TfsOdataAlmRangers, вместо c:\odata.

Примечание

Для тестирования, можно использовать самозаверяющийся сертификат. Один из способов сделать это, с использованием IIS Manager перейти в узел машины, открыть Server Certificates и выбрать Create Self-Signed Certificate. Чтобы узнать больше о SSL и IIS, смотрите http://learn.iis.net/page.aspx/144/how-to-set-up-ssl-on-iis-7/
4. Импортировать сертификат[ ] — Сделано
  • Перейдите по адресу https://localhost:433/ и вы получите следующее предупреждение

  • Нажмите на ссылку Continue to this website. Поле URL станет красным и отобразит ошибку сертификата

  • Нажмите на ошибку, выберите Показать сертификат и импортируйте сертификат.
5. Добавить сертификат[ ] — Сделано
  • С этого момента сервисы OData готовы к использованию.

Таблица 11. Руководство: Развертывание служб OData на сервере IIS

<<Содержание

Advertisements

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

 
%d такие блоггеры, как: