Автоматизация управления пользователями IBM Rational Team Concert

Источник: IBM

Обзор

IBM Rational Team Concert - это программное обеспечение для совместного планирования проектов и управления изменениями. На одном сервере Rational Team Concert может размещаться несколько областей проектов (project area). Области проектов служат рабочими областями для различных групп пользователей.

Администратор Rational Team Concert управляет правами пользователей либо через имеющийся пользовательский интерфейс, либо посредством Java API. Выбор интерфейса зависит от объема работы.

Пользовательский интерфейс удобен, если нужно сделать всего несколько изменений для небольшой группы пользователей.

API больше подходит для множественных изменений или для изменений, касающихся большой группы пользователей. Два примера:

  • Добавление большого числа пользователей в Rational Team Concert при выполнении процесса миграции.
  • Управление доступом на основе изменений в другой системе (например, архивация учетной записи пользователя при удалении его из корпоративного каталога).

В обеих ситуациях API исключает вмешательство системного администратора и позволяет автоматизировать рутинную работу. Источники данных о пользователях для Rational Team Concert могут быть разными, от обычного файла до существующей системы управления изменениями или корпоративного каталога.

В данной статье рассказывается, как использовать Rational Team Concert API для создания, активации и архивирования данных о пользователях в Rational Team Concert.

Сценарий

Есть два способа использования пользовательского интерфейса Rational Team Concert для добавления пользователей: создание пользователей или импорт.

Проблема

Ограничением использования пользовательского интерфейса при любом способе является то, что администратор может добавлять пользователей только по одному. Это ограничение становится проблемой при необходимости добавления группы пользователей, например, если нужно импортировать в Rational Team Concert данные о пользователях из другой системы.

Два других аспекта управления пользователями - это архивирование и активация их учетных записей. Администратор может выполнить данные операции при помощи пользовательского интерфейса, но это становится непростой задачей при необходимости синхронизации двух систем (Rational Team Concert и любой другой системы управления изменениями). При ручном режиме необходимо участие администратора Rational Team Concert во всем процессе репликации пользовательских настроек Active или Archive из другой системы управления изменениями.

Решение

Создание пользователей с использованием API устраняет эти ограничения. В этом автоматизированном режиме пользователи создаются программным способом посредством чтения данных из любой существующей системы. Такой подход помогает также в ситуациях, когда две системы (Rational Team Concert и любая другая система управления изменениями) не синхронизированы, и данные о пользователях необходимо создавать, архивировать или восстанавливать автоматически, не ожидая вмешательства администратора для синхронизации обеих систем.

Управление пользователями посредством пользовательского интерфейса

Ниже приведено краткое описание действий по управлению пользователями в Rational Team Concert посредством пользовательского интерфейса, проиллюстрированное снимками экрана. Для выполнения этих действий необходимо иметь права администратора Rational Team Concert.

Создание пользователя

  1. Войдите на сервер Rational Team Concert, используя Web-клиент.
  2. Перейдите на вкладку Users и нажмите кнопку Create User.
  3. Добавьте необходимые данные о пользователе и сохраните их.

Рисунок 1. Создание пользователя в Rational Team Concert
Рисунок 1. Создание пользователя в Rational Team Concert

Увеличенная версия рисунка 1.

Импорт пользователей из какой-либо другой службы каталогов

  1. Войдите на сервер Rational Team Concert, используя Web-клиент.
  2. Перейдите на вкладку Users и нажмите кнопку Import Users.
  3. Просмотрите список и выберите пользователя, которого хотите импортировать.

Рисунок 2. Импорт пользователей
Рисунок 2. Импорт пользователей

Увеличенная версия рисунка 2.

Рисунок 3. Окно Select Users в Import Users
Рисунок 3. Окно Select Users в Import Users

Рисунок 4. Подтверждение: User imported successfully (успешный импорт пользователя)
Рисунок 4. Подтверждение: User imported successfully (успешный импорт пользователя)

Увеличенная версия рисунка 4.

Архивирование активных пользователей

  1. Войдите на сервер Rational Team Concert, используя Web-клиент.
  2. Перейдите на вкладку Users и нажмите кнопку Active Users.
  3. Выберите пользователя и нажмите кнопку Archive User в столбце Action, как показано на рисунке 5.

Рисунок 5. Архивирование пользователей в Rational Team Concert
Рисунок 5. Архивирование пользователей в Rational Team Concert

Увеличенная версия рисунка 5.

Восстановление архивированных пользователей

  1. Войдите на сервер Rational Team Concert, используя Web-клиент.
  2. Перейдите на вкладку Users и нажмите кнопку Archived Users.
  3. Выберите пользователя и нажмите кнопку Restore User в столбце Action, как показано на рисунке 6.

Рисунок 6. Восстановление пользователей
Рисунок 6. Восстановление пользователей

Увеличенная версия рисунка 6.

Программное управление пользователями посредством API

Все предыдущие действия можно выполнить и при помощи Rational Team Concert API. Программирование с использованием API автоматизует и стандартизирует процесс, а также ускоряет его и устраняет ошибки при массовой обработке учетных данных пользователей.

Примечание.
Чтобы использовать эти методы, необходимо принадлежать к группе JazzAdmins.

Создание пользователя

Как показано в листинге 1, настройка требуемых данных о пользователе в объекте класса IContributor и сохранение этого объекта посредством Contributor Manager создаст нового пользователя в Rational Team Concert.

Листинг 1. Создание пользователя посредством Rational Team Concert API

private IContributor createRTCUser(ITeamRepository repo,String userName,String 
emailAddress,String userId) throws TeamRepositoryException{ 
//Создание элемента с типом Contributor и настройка его свойств
IContributor i1 = (IContributor) IContributor. ITEM_TYPE .createItem(); 
i1.setName(userName); 
i1.setUserId(userId); 
i1.setEmailAddress(emailAddress); 
i1.setArchived(false); 
return repo.contributorManager().saveContributor(i1, null); 
}

Импорт и создание пользователей посредством API

Rational Team Concert также предоставляет способ импорта пользователей непосредственно из внешнего реестра пользователей в репозиторий Rational Team Concert. Для того сервер Rational Team Concert необходимо настроить на использование ExternalUser Registry (LDAP в примере листинга 2).

Листинг 2. Импорт пользователя из реестра ExternalUser Registry

private boolean importUserToRTC(ITeamRepository repo,IContributor cont) throws 
TeamRepositoryException{ 
//Получение ExternalUser Registry и извлечение необходимого пользователя 
IExternalUserRegistryManager externalUserRegMgr = repo.externalUserRegistryManager(); 
IExternalUser exUser = externalUserRegMgr.fetchUser("test1@in.ibm.com", null); 
if (exUser!=null) { 
    //Импорт найденного пользователя из ExternalUser Registry
    cont = (IContributor) cont.getWorkingCopy(); 
    cont.setEmailAddress(exUser.getEmailAddresses().get(0)); 
    cont.setName(exUser.getFullNames().get(0)); 
    cont.setUserId(exUser.getUserId()); 
    cont.setArchived(false); 
    cont = repo.contributorManager().saveContributor(cont, null); 
    return true; 
} 
else{ 
    System. out .println("User doesn't exist in ExternalUser Registry"); 
    return false;
} 
}

Архивирование и восстановление пользователей

После архивирования в Jazz Repository учетных записей эти пользователи больше не смогут войти в Rational Team Concert Server до тех пор, пока не будет восстановлено их активное состояние.

Листинг 3. Метод архивирования пользователя в Rational Team Concert

public void archiveUsers(ITeamRepository repo) 
throws TeamRepositoryException{ 
// Архивирование пользователя в Rational Team Concert 
IContributor cont = repo.contributorManager() 
    .fetchContributorByUserId("user_id", null); 
if (cont.isArchived()) 
    return; 
cont = (IContributor) cont.getWorkingCopy(); 
cont.setArchived(true); 
repo.contributorManager().saveContributor(cont, null); 
}

Листинг 4. Метод восстановления архивированного пользователя

public void restoreUser(ITeamRepository repo) 
    throws TeamRepositoryException, IOException{ 
IContributor cont = repo.contributorManager(). 
fetchContributorByUserId(("abc@in.ibm.com"), null); 
if (!cont.isArchived()) 
return; 
// Восстановление пользователя в Rational Team Concert 
cont = (IContributor) cont.getWorkingCopy(); 
cont.setArchived(false); 
repo.contributorManager().saveContributor(cont, null); 
}

Синхронизация пользователя с внешним репозиторием

Для интеграции Rational Team Concert с любой другой внешней системой может потребоваться миграция данных с целью поддержки синхронизации между двумя этими репозиториями. В противном случае обновления данных о пользователе, выполненные в одной системе, могут не отразиться в другой, если пользователь не существует в другом репозитории. Поэтому пользователи в двух репозиториях должны быть синхронизированы. В данном примере мы для простоты извлечем информацию о пользователе из файла свойств. В реальной ситуации нужно извлекать данные о пользователе из внешнего репозитория системы управления изменениями.

Рисунок 7. Синхронизация пользователей между двумя репозиториями
Рисунок 7. Синхронизация пользователей между двумя репозиториями

Отображение свойств пользователей между двумя репозиториями

Необходимо создать правило синхронизации пользователей для определения способа отображения свойств элемента Rational Team Concert на поля объекта внешнего репозитория.

  1. Создайте правило User Synchronization (в данном примере Rational Team Concert-User.xml).
  2. Затем вставьте следующие значения полей:

Раздел отображения типов

Поле

Значение

Item Type (тип элемента) Contributor - com.ibm.team.repository
Item Type Qualifier (спецификатор типа элемента) Оставьте пустым
Item Manager (менеджер элементов) Contributor Manager
External Repository (внешний репозиторий) Имя внешнего репозитория
External Manager (внешний менеджер) Менеджер внешнего репозитория для пользователя (различные варианты)  
External Type (внешний тип) User

Раздел свойств

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

Свойство элемента

Распространение

Внешнее свойство

EmailAddress Оба направления address
Name Оба направления name
UserId Оба направления user_id
Login    
Repository name    

На рисунке 8 приведен снимок экрана разработанного файла правила синхронизации.

Примечание.
Для данного примера мы взяли unique_identifier в качестве внешнего идентификатора и User_id в качестве идентификатора элемента. Уникальным идентификатором может быть все, что уникально во внешнем репозитории, либо комбинация двух или трех внешних свойств. Здесь в качестве уникального идентификатора используется комбинация регистрационного имени (login), знака подчеркивания и имени файла свойств, например: login_имя файла свойств.

Рисунок 8. Правило синхронизации пользователей
Рисунок 8. Правило синхронизации пользователей

Увеличенная версия рисунка 8.

Синхронизация пользователей с Rational Team Concert

В этом примере мы предполагаем, что необходимые для синхронизации с Rational Team Concert данные о пользователях содержатся в простом файле свойств User.properties (содержимое файла приведено в листинге 5). Администратор создает программу, читающую этот файл и преобразующую данные о пользователях в список пользователей, чтобы можно было синхронизировать их с Rational Team Concert.

Листинг 5. Содержимое файла User.properties

#Данные о пользователях, сохраненные в простом файле свойств

#Данные о пользователе 1

login = Test1 
email_address = test1@in.ibm.com 
name = Test1 User 
user_id = test1@in.ibm.com 
deleteDate = 12/08/2011 

#Данные о пользователе 2

login = Test2 
email_address = test2@in.ibm.com 
name = Test2 User 
user_id = test2@in.ibm.com 
deleteDate = 20/02/2012 

Таким образом, данные о каждом пользователе будут помещены в хэш-карту, которая использует соответствующие названия полей (login, email_address, name, user_id, deleteDate) в качестве ключей. Каждую UserHashMap следует добавить в объект ArrayList. Мы выполним итерирование по этому списку для программной синхронизации пользователей с Rational Team Concert.

Прежде всего проверим, существует ли прокси-объект синхронизируемого пользователя (см. листинг 6). Прокси-объект пользователя является представлением пользователя между внешним репозиторием и репозиторием Jazz. Он ассоциирован с URI внешнего объекта, который по сути является уникальным идентификатором для внешнего объекта. Если он существует, это означает, что пользователь уже синхронизирован, т.е. во время выполнения синхронизации данный идентификатор нужно пропустить.

Листинг 6. Метод для проверки существования прокси-объекта пользователя

private boolean 
userProxyExists(ITeamRepository repo,String uniqueIdentifier,String login)throws 
URISyntaxException, TeamRepositoryException{ 
IInteropManager interopManager = (IInteropManager) 
repo.getClientLibrary(IInteropManager.class); 
URI u = new URI(uniqueIdentifier); 
IExternalProxy proxy = interopManager.findProxybyUri(u, null); 

if (proxy != null) { 
    System. out .println("User with login id :" + login + " is already synched in 
Rational Team Concert "); 
    return true; 
}else
    return false; 
} 
}

Если прокси-объект пользователя не существует, синхронизация продолжается. Возможно, что прокси-объект пользователя не существует, но соответствующий пользователь уже имеется на сервере Rational Team Concert. Это означает, что пользователь был импортирован в Rational Team Concert ранее, возможно, из другого репозитория. В таких случаях решение о продолжении обработки должен принимать администратор. В примере, приведенном в листинге 7, в подобных случаях просто меняются имена и адреса электронной почты пользователей.

Листинг 7. Метод для синхронизации пользователя с Rational Team Concert

public void syncUser(ITeamRepository jazzRepo,IProjectAreaHandle 
projectAreaHandle,Map<String,String> UserMap) throws 
TeamRepositoryException, URISyntaxException 
{

String address = (String) UserMap.get("email_address"); 
IContributor cont =null; 
try { 
    cont = fTeamRepository.contributorManager().fetchContributorByUserId(address, null);
}catch (ItemNotFoundException e) { 
    System. out .println("User :" + address +" 
    not found in contributorManager repository"); 
} 
if (cont != null) { 
    // пользователь с таким идентификатором уже есть в Rational Team Concert
    // просто измените имя для устранения конфликтной ситуации.
    UserMap.put("name", cont.getName()); 
    UserMap.put("email_address", cont.getEmailAddress()); 
} 
else 
    {//Объект Contributor не существует в Rational Team Concert. Импортировать User
из 
    ExternalUserRegistry 
    if (manager == null) 
    manager = fTeamRepository.externalUserRegistryManager(); 
    IExternalUser user = null; 
    user = manager.fetchUser(address, new NullProgressMonitor()); 
    if (user!=null) 
        System. out .println("User found in directory service :"+ address); 
} 
//Извлечь правило синхронизации пользователя для получения внешнего идентификатора
IInteropManager interopManager = (IInteropManager) 
jazzRepo.getClientLibrary(IInteropManager.class); 
ISyncRuleHandle[] syncRuleHandles = interopManager 
.findSyncRulesByExternalTypeNameAndProjectArea("User",projectAreaHandle, null); 
ISyncRule syncRule = (ISyncRule) fTeamRepository.itemManager() 
.fetchCompleteItem(syncRuleHandles[0],IItemManager. REFRESH , null); 

IPropertyMapping externalIDmapping = syncRule 
.getExternalIdentifierPropertyMapping(); 

String externalID = externalIDmapping.getExternalPropertyName(); 

String uniqueId = (String) UserMap.get(externalID); 
URI u = new URI(uniqueId); 
IExternalProxy proxy = interopManager.findProxybyUri(u, null); 
IExternalState externalState = null; 

if (proxy == null) { 
    System. out .println("Creating a new proxy."); 
    proxy = InteropFactory. INSTANCE .createExternalProxy(); 
    proxy.setSyncRule(syncRule); 
    proxy = interopManager.saveProxyWithUri(proxy, u, null); 
    } 
if (proxy.getExternalStateItemHandle() == null) { 
    externalState = InteropFactory. INSTANCE .createExternalState(); 
} else {
    externalState = (IExternalState) interopManager 
    .getExternalState(proxy, null).getWorkingCopy(); 
    } 
externalState.setState(UserMap); 
externalState = interopManager.saveExternalState(externalState,null); 
proxy = 
interopManager.synchronizeIncomingAndWait(proxy,externalState,null,syncRule ,null); 

SynchronizationStatus syncStatus = proxy.getSynchronizationStatus(); 
if (syncStatus != SynchronizationStatus. INCOMING_ERROR ) { 
    // Проверить, существуют ли какие-либо блокирующие прокси-объекты,
    // и отобразить состояние при их наличии.
    
    IExternalProxyHandle[] blockingProxies = interopManager 
    .getBlockingProxies(proxy, true, null); 
        if (blockingProxies.length != 0) { 
            System. out .println("Synchronization is blocked for 
          User"+UserMap.get("name")); 
          } else 
            System. out .println("Synchronization for User + "+UserMap.get("name")+
            "successfully completed"); 
}
else { 
    System. out .println("Synchronization has error for User + 
    "+UserMap.get("name")+ "Error is"+proxy.getLastErrorString()); 
    } 
}

Если Contributor не существует, данные пользователя импортируются из внешнего реестра пользователей (LDAP в данном примере). Значение внешнего идентификатора извлекается из UserMap и формируется соответствующий URI. Если ExternalProxy, соответствующий этому URI, не существует, создается прокси-объект, устанавливается соответствующее правило syncRule и объект сохраняется. UserMap сохраняется как ExternalState прокси-объекта, после чего активизируется завершение синхронизации данного пользователя. Процесс синхронизации будет ожидать завершения этого запроса, прежде чем синхронизировать других пользователей. Результатом успешного завершения запроса является полное состояние прокси-объекта после обработки возвращенного результата. Если успешного возврата запроса не происходит (из-за прекращения или отмены, а не из-за ошибки синхронизации), возвращается значение null. В процессе синхронизации пользователя могут возникать следующие состояния:

UNINITIALIZED
Указывает на то, что внешнее состояние еще не получено. Это состояние по умолчанию для вновь созданного прокси-объекта.
 
OK
Последнее известное состояние внешнего объекта было синхронизировано с последним известным состоянием элемента Jazz без каких-либо ошибок.
 
PENDING
Операция находится в режиме ожидания прокси-объекта.
 
INCOMING ERROR
Процесс синхронизации завершился неудачно по какой-либо причине.
 

Существует вероятность того, что синхронизация пользователя по какой-либо причине может блокироваться. В таких случаях необходимо удалить прокси-объект, чтобы можно было попытаться синхронизировать его снова. Если состояние равно INCOMING ERROR, можно извлечь причину ошибки и предпринять действия по устранению повторных ошибок подобного рода.

Этот процесс будет выполняться для всех пользователей, которые нуждаются в синхронизации. Состояние синхронизации можно проверить, щелкнув правой кнопкой мыши на правиле синхронизации пользователя в окне Synchronization Rules View и выбрав Show Unsynchronized.

Совет.
Лучше использовать метод synchronizeIncomingAndWait, чем synchronizeIncoming, поскольку он ждет завершения запроса и затем переходит к обработке следующих запросов синхронизации независимо от метода synchronizeIncoming. Он помещает запрос в конец очереди синхронизации и немедленно возвращает управление без проверки завершения. Это может привести к появлению ошибок или блокировке прокси-объектов других элементов синхронизации (дефектов или возможностей), на которые могут ссылаться пользователи и которые все еще ожидают в очереди синхронизации.

Архивирование и восстановление пользователей

Если пользователь больше не существует во внешнем репозитории из-за того, что он был архивирован или удален, для синхронизации внешних объектов, на которые ссылается данный пользователь, необходимо выполнить архивирование такого пользователя на сервере Rational Team Concert. Проверить, был ли архивирован Contributor на сервере, можно путем вызова его метода isArchived(), cont.isArchived(), который возвратит True, если пользователь архивирован на сервере, и False, если нет.

Для запуска синхронизации между репозиториями необходимо сначала восстановить архивированных пользователей, после чего выполнить синхронизацию внешних объектов и затем снова архивировать пользователей на сервере Rational Team Concert. Восстановление пользователей необходимо для успешной синхронизации внешних объектов, поскольку архивированные пользователи не смогут входить в репозиторий. В листинге 8 показано, как восстановить архивированного пользователя Rational Team Concert. Здесь можно передать UserMap.get("user_id") для выборки contributor по user_id.

После завершения синхронизации необходимо снова архивировать удаленных пользователей. Будут архивироваться пользователи, имеющие удаленные даты в UserMap.

Листинг 8. Метод для архивирования пользователей в Rational Team Concert

public void archiveUsers(ITeamRepository repo, Map<String,String> UserMap){ 
for(String key :UserMap.keySet()){ 

    if (UserMap.get("deleteDate")!= null && !(UserMap.get("deleteDate").equals(""))) { 
        // Архивирование пользователя в Rational Team Concer
        IContributor cont = repo.contributorManager() 
        .fetchContributorByUserId(UserMap.get("user_id"), null); 
        if (cont.isArchived()) 
            continue; 
        cont = (IContributor) cont.getWorkingCopy(); 
        cont.setArchived(true); 
        repo.contributorManager().saveContributor(cont, null); 
        }
}
}

Таким образом, обновления этих пользователей будут реплицироваться в репозиторий Jazz на архивированных пользователей.

Синхронизация пользователей Rational Team Concert с внешним репозиторием

Синхронизация пользователей из Rational Team Concert с внешним репозиторием включает в себя исходящую синхронизацию (Outgoing Synchronization) из сервера Rational Team Concert с внешним репозиторием. По умолчанию процесс Outgoing Synchronization на сервере Jazz отключен. Информация по его включению и созданию подключения к внешнему репозиторию приведена в информационном центре "Управление изменениями в Rational Team Concert".

Мы создадим класс, который будет реализовывать интерфейс IInteropExternalManager и расширять абстрактный класс AbstractInteropExternalManager. Этот класс активизирует процесс Outgoing Synchronization из сервера Rational Team Concert. Класс будет реализовывать методы canCreateObject, updateState, createObject и findObject для полного выполнения процесса Outgoing Synchronization и возврата результата любого обновления или создания во внешнем репозитории обратно на Rational Team Concert.

Для простоты мы опять возьмем файл свойств и создадим или обновим в нем данные о пользователе. На практике обычный файл можно заменить любым внешним репозиторием и выполнять создание или обновление данных о пользователе через его API. Дополнительная информация приведена в статье "Реализация внешнего репозитория".

Исходящая синхронизация происходит следующим образом:

  1. Метод findObject пытается найти существующие объекты во внешнем репозитории.
  2. Если в нем обнаруживается подходящий объект, возвращаются текущие свойства этого объекта и вызывается метод getState для извлечения текущего состояния подключенного внешнего объекта. Для обновления изменений существующего внешнего объекта могут быть применены значения соответствующих свойств.
  3. Если объект не найден, во внешнем репозитории создается новый объект, при условии, что значение CanCreateObject установлено в True.

Листинг 9. Метод поиска внешнего объекта (findObject) в файле свойств

public URI findObject(final String typeName, final String idPropName, 
final Map<String, ?> state,final Map<String, Object> returnedState, 
final List<String> propertyNames,final 
IExternalRepositoryConnection externalConnection) { 
String uniqueID = ""; 
String name = null; 
try { 
    if(idPropName==null) 
        return null; 
    if(state.containsKey(idPropName)){ 
        name = (String) state.get(idPropName); 
        if(name ==null) 
        return null; 
    }else{ 
        System. out .println("Unique property not available"); 
        return null; 
    } 
    Map<String,Object> externalState = new HashMap<String,Object>(); 
    HashMap UserMap = new HashMap(); 
    uniqueID = (String) state.get(idPropName); 
    String temp[] = uniqueID.split("_"); //uniqueID is combination of login External 
    Repository (property file in our case) 
    String login = temp[0]; 
    Properties propertyValues = new Properties(); 
    // Чтение файла свойств
    readPropertyFile(propertyValues); 
    //Получить значение свойства по его ключу
    Object value = propertyValues.getProperty(login); 
    if(value!=null){ 
        UserMap.put("login", value); 
        UserMap.put("email_address", propertyValues.getProperty("email_address")); 
        UserMap.put("name", propertyValues.getProperty("name")); 
        UserMap.put("user_id", propertyValues.getProperty("user_id")); 
        UserMap.put("deleteDate", propertyValues.getProperty("deleteDate ")); 
        externalState = UserMap; 
        }else
            return null; 
        
        returnedState.putAll(externalState); 
        return URI. create ((String)returnedState.get("uniqueID")); 
        } catch (final Exception erEx) { 

            ExceptionHandler. handleException (erEx); 
            throw new RuntimeException(erEx); 
        } 
    } 
// Чтение файла свойств 
public void readPropertyFile(Properties propertyValues) throws IOException{ 
File dir = new File("file:\\C:\\User.properties"); 
String url = dir.toString(); 
InputStream stream = null; 
String path = "C:\\User.properties"; 

URL fileURL = new URL(url); 
stream = fileURL.openStream(); 
stream = new FileInputStream(path); 
propertyValues.load(stream); 
}

Вызванный выше метод Find найдет данные о пользователе в файле свойств по регистрационному имени, извлекаемому из unique_identifier. Этот метод создаст и возвратит URI пользователя, если он будет обнаружен в файле свойств. В противном случае он вернет значение null .

Метод создания внешнего объекта (createObject)

Если findObject() возвращает null (если внешнее состояние объекта равно null, это означает, что внешнего объекта с требуемым unique_identifier не существует), внешний объект может быть создан в зависимости от того, хочет администратор создать его во внешнем репозитории или нет. Если администратор требует создания внешнего объекта во внешнем репозитории, canCreateObject возвратит True, и InteropService вызовет метод createObject, создавая тем самым внешний объект во внешнем репозитории (в нашем примере данные для нового пользователя будут добавлены в файл свойств), и возвратит объект CreationInfo.

Листинг 10. Метод для создания объекта во внешнем репозитории

public boolean canCreateObject(String typeName) {
// Пользователи могут быть созданы в ExternalRepository 
return true; 
} 

public CreationInfo createObject(final String typeName, 
final Map<String, ?> state,final Map<String, Object> returnedState, 
final List<String> propertyNames,final IExternalRepositoryConnection externalConnection,
final IProcessArea processArea) { 
                
Properties propertyValues = new Properties(); 
URI uri = null; 
String address = (String) state.get("address"); 
String name = (String) state.get("name"); 
String userId = (String) state.get("user_id"); 
Map<String,String> UserMap =new HashMap<String,String>(); 
Map<String,String> externalState = new HashMap<String, String>(); 

/*Запрос, существует User в User.properties или нет */ 
try {
    readPropertyFile(propertyValues); 
} catch (IOException e) { 

    e.printStackTrace(); 
} 
Object value = propertyValues. getProperty (userId); 
if(value==null // value.toString().equals("")){ 
//Поместить данные о User, поскольку пользователь не существует в User.properties 
    propertyValues.setProperty("name2", name); 
    propertyValues.setProperty("user_id2", userId); 
    propertyValues.setProperty("email_address2", address); 
    propertyValues.setProperty("login2", userId); 
    propertyValues.setProperty("deleteDate2", ""); 
    try { 
    propertyValues.store(new FileOutputStream("C:\\User.properties",true), 
    "User3 details"); 
    } catch (FileNotFoundException e) { 
    
        e.printStackTrace(); 
    } catch (IOException e) { 

        e.printStackTrace(); 
    } 
    uri = URI. create (userId+"_"+"User.properties"); 
    } else 
    //Пользователь уже существует в External Repository, просто создать uri 
    uri = URI. create (value+"_"+"User.properties"); 

    UserMap.put("address", address); 
    UserMap.put("name", name); 
    UserMap.put("user_id", userId); 
    externalState = UserMap; 
    if (externalState == null) { 
    return null; 
    } 
returnedState.putAll(externalState); 
return new CreationInfo(uri, null); 
}

Таким образом, если пользователь не найден в файле User.properties и canCreateObject установлен в True, в файл свойств будет добавлен новый пользователь.

Метод обновления внешнего объекта (updateState)

Этот метод обновляет состояние внешнего объекта в файле свойств. После успешного обновления он возвращает сохраненное состояние. Администратор может также обновить и внешний репозиторий. В примере, приведенном в листинге 11, просто обновляется файл свойств в случае изменения имени пользователя на сервере Rational Team Concert.

Листинг 11. Метод для обновления объекта во внешнем репозитории

public boolean updateState(final String typeName, final URI uri,final Map<String, ?> 
newState, 
final Map<String, ?> lastState,final Map<String, Object> returnedState,final List<String> 
propertyNames,final ExternalRepositoryConnection externalConnection,final IProcessArea 
processArea) { 
Properties propertyValues = new Properties(); 
HashMap UserMap = new HashMap(); 
Map<String,Object> newMap = null; 
//Выполнение итерации по newState, извлеченному с сервера Rational Team Concert,
//и обновление файла свойств только в случае изменения имени пользователя

for (Iterator<String> it = newState.keySet().iterator(); it.hasNext();){ 
    String key = it.next(); 
    if(key.equals("name")){ 
    String s2 = (String)newState.get(key); 
    //Обновление UserName в файле свойств 
    try { 
        readPropertyFile(propertyValues); 
    } catch (IOException e) { 

        e.printStackTrace(); 
    } 
    propertyValues.setProperty(key, s2); 
    try { 
        propertyValues.store(new FileOutputStream("C:\\User.properties",true), "User3 
    details"); 
    } catch (FileNotFoundException e) { 

        e.printStackTrace(); 
    } catch (IOException e) { 

        e.printStackTrace(); 
    } 
    UserMap.put("login", propertyValues.getProperty("login")); 
    UserMap.put("email_address", propertyValues.getProperty("email_address")); 
    UserMap.put("name", propertyValues.getProperty("name")); 
    UserMap.put("user_id", propertyValues.getProperty("user_id")); 
    UserMap.put("deleteDate", propertyValues.getProperty("deleteDate ")); 
    newMap = UserMap; 
    
    returnedState.putAll(newMap); 
    return true; 
    } 
    } 
    return false; 
}

Совет.
Этот исходный код содержится в файле SynchroniseUser.zip.

Заключение

Вы узнали, как администратор Rational Team Concert может создавать, импортировать, синхронизировать и управлять учетными записями пользователей Rational Team Concert во внешнем и Jazz-репозиториях во время исполнения, не делая ничего вручную. Использование Rational Team Concert API экономит время при выполнении процесса синхронизации репозиториев.

 

Загрузка

Описание

Имя

Размер

Метод загрузки

Примеры сценариев SynchroniseUser.zip 6 КБ HTTP 


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=31008