Механизм отключения функциональности Feature Toggle

PDF
Средний

Feature toggle — техника разработки программных продуктов, которая обеспечивает поддержку подключения дополнительной функциональности в работающем приложении. Это позволяет использовать непрерывную интеграцию, сохраняя работоспособность приложения и скрывая функциональность, которая находится в стадии разработки.

Основная идея заключается в том, что в исходном коде имеется блок с дополнительной функциональностью (зачастую не полностью реализованной) и условный оператор, в котором определяется, подключена ли данная функциональность.

Включить функциональность

Для текущего пользователя системы

Для включения или выключения функциональности для текущего пользователя системы предназначена специальная страница FeaturesPage. Страница FeaturesPage используется для точечного включения функциональности для тестирования.

[Адрес приложения]/0/Nui/ViewModule.aspx#BaseSchemaModuleV2/FeaturesPage
http://myсreatio.com/0/Nui/ViewModule.aspx#BaseSchemaModuleV2/FeaturesPage

Чтобы включить или выключить функциональность, используйте соответствующий переключатель(1). Для применения изменений нажмите кнопку Сохранить изменения (Save changes) (2). Во всплывающей подсказке (3) отображается статус функциональности для группы пользователей, в которую входит текущий пользователь. Функциональность может быть включена в базе данных для группы пользователей, при этом выключена для текущего пользователя. И наоборот функциональность может быть отключена для группы пользователей, но включена для текущего пользователя.

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

Для всех пользователей системы

Для включения или выключения функциональности для всех пользователей системы необходимо выполнить специальный запрос к базе данных. В примере запроса, приведенном ниже, в переменной featureCode следует указать необходимое название функциональности.

Запрос на включение функциональности для всех пользователей
MSSQL
PosrgreSQL
ORACLE
DECLARE @featureCode varchar(max) = 'NewEmailSettingsWithoutAutoSynchronization',
 @featureId uniqueidentifier;
set @featureId = (select top 1 Id from Feature where Code = @featureCode);
IF @featureId is null
BEGIN
 insert into Feature
  (Name, Code)
 values
  (@featureCode, @featureCode);
 set @featureId = (select top 1 Id from Feature where Code = @featureCode);
END;
delete from AdminUnitFeatureState where FeatureId = @featureId;
insert into AdminUnitFeatureState
 (SysAdminUnitId, FeatureState, FeatureId)
values
 ('A29A3BA5-4B0D-DE11-9A51-005056C00008', 1, @featureId),
 ('720B771C-E7A7-4F31-9CFB-52CD21C3739F', 1, @featureId);
do $$
DECLARE
featureCode varchar(100) = 'EmailIntegrationV2';
featureId UUID;
BEGIN
featureId = (select "Id" from "Feature" where "Code" = featureCode limit 1);
IF featureId is null THEN
insert into "Feature"
("Name", "Code")
values
(featureCode, featureCode);
featureId = (select "Id" from "Feature" where "Code" = featureCode limit 1);
end IF;
delete from "AdminUnitFeatureState" where "FeatureId" = featureId;
insert into "AdminUnitFeatureState"
("SysAdminUnitId", "FeatureState", "FeatureId")
values
('A29A3BA5-4B0D-DE11-9A51-005056C00008', 1, featureId),
('720B771C-E7A7-4F31-9CFB-52CD21C3739F', 1, featureId);
end $$;
DECLARE
 existObject NUMBER := 0;
 v_featurecode VARCHAR2(50) := 'LoadAttachmentsInSameProcess';
 v_featureid VARCHAR2(38);
BEGIN
 SELECT COUNT(1) INTO existObject FROM "Feature" WHERE "Code" = v_featurecode;
 if existObject = 0 THEN 
  INSERT INTO "Feature" ("Name", "Code") VALUES (:v_featurecode, :v_featurecode);
 END IF; 
 SELECT "Id" INTO v_featureid FROM "Feature" WHERE "Code" = v_featurecode AND rownum <= 1;
 DELETE FROM "AdminUnitFeatureState" WHERE "FeatureId" = v_featureid;
 INSERT INTO "AdminUnitFeatureState" ("SysAdminUnitId", "FeatureState", "FeatureId") 
  VALUES ('{A29A3BA5-4B0D-DE11-9A51-005056C00008}', 1, v_featureid);
END;
/

Запрос на выключение функциональности будет отличаться только значением 0, передаваемым в колонку [FeatureState] таблицы [AdminUnitFeatureState].

Важно. Функциональность, которая была включена через запрос к базе данных, может быть выключена только соответствующим запросом к базе данных.

Добавить функциональность 

Для добавления новой отключаемой функциональности укажите ее код, название и краткое описание, а затем нажмите кнопку Добавить функциональность (Create feature).

Хранение сведений о функциональности в базе данных 

Перечень доступной для включения/отключения функциональности хранится в таблице Feature базы данных приложения. По умолчанию таблица пуста. Основные поля таблицы [Feature] приведены в таблице.

Основные поля таблицы [Feature]
Название Тип Описание
Id uniqueidentifier Уникальный идентификатор записи.
Name varchar( 250 ) Название функциональности.
Code varchar( 50 ) Код функциональности.

Информация о состоянии функциональности (включена/отключена) содержится в поле FeatureState таблицы [AdminUnitFeatureState]. Таблица [AdminUnitFeatureState] связывает таблицы [Feature] и [SysAdminUnit], в которой определены пользователи и группы пользователей системы. Основные поля таблицы [AdminUnitFeatureState] приведены в таблице.

Основные поля таблицы [AdminUnitFeatureState]
Название Тип Описание
Id uniqueidentifier Уникальный идентификатор записи.
FeatureId uniqueidentifier Уникальный идентификатор записи функциональности.
SysAdminUnitId uniqueidentifier Уникальный идентификатор записи пользователя.
FeatureState int Состояние функциональности. 1 — включена, 0 — выключена.
Диаграмма взаимосвязи таблиц

Определение новой функциональности в программном коде 

Для внедрения дополнительной функциональности в исходный код ее необходимо определять в блоке условного оператора, который проверяет состояние подключения функциональности FeatureState.

JavaScript на стороне клиента 

Условный шаблон определения дополнительной функциональности в программном коде
// Метод, в котором определяется дополнительная функциональность.
someMethod: function() {
	// Проверка подключения функциональности.
	if (Terrasoft.Features.getIsEnabled("код функциональности")) {
		// Реализация дополнительной функциональности.
		...
	}
	// Реализация метода.
	...
}

Для повышения удобства использования в состав базовой схемы модели представления BaseSchemaViewModel введен метод getIsFeatureEnabled. Поэтому метод Terrasoft.Features.getIsEnabled можно заменить на this.getIsFeatureEnabled("код функциональности").

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

C# на стороне сервера 

Для использования Feature toggle в схемах исходного кода на серверной стороне в классе Terrasoft.Configuration.FeatureUtilities был реализован набор расширяющих методов класса UserConnection. Перечень расширяющих методов приведен в таблице. В этом же классе объявлено перечисление состояний функциональностей FeatureState.

Основные методы класса DataManager

int GetFeatureState( this UserConnection source, string code )

Возвращает состояние функциональности.

Параметры
code код функциональности.
Dictionary <string, int> GetFeatureStates( this UserConnection source )

Возвращает состояния всех функциональностей.

void SetFeatureState( this UserConnection userConnection, string code, int state, bool forAllUsers = false )

Устанавливает состояние функциональности.

Параметры
code код функциональности;
state состояние функциональности (0/1);
forAllUsers признак установки функциональности для всех пользователей.
void CreateFeature( this UserConnection source, string code, string name, string description )

Создает новую функциональность.

Параметры
code код функциональности;
name название функциональности;
description описание функциональности.
bool GetIsFeatureEnabled( this UserConnection source, string code )

Проверяет подключена ли функциональность.

Параметры
code код функциональности.
Условный шаблон определения дополнительной функциональности в программном коде
…
// Пространство имен, в котором определена возможность переключения 
// дополнительной функциональности.
using Terrasoft.Configuration;
…
// Метод, в котором будет определяться дополнительная функциональность.
public void AnyMethod() {
	// Проверка, включена ли функциональность.
    if (UserConnection.GetIsFeatureEnabled("код функциональности")) {
		// Реализация дополнительной функциональности.
    }
	// Реализация метода.
	...
}

Установка значения состояния функциональности выполняется вызовом метода SetFeatureState.

Вызов метода SetFeatureState
UserConnection.SetFeatureState("код функциональности", FeatureState);