Позволяет изменить параметры информационной базы, зарегистрированной в кластере. Изменять можно только словесное описание информационной базы.
Синтаксис
UpdateInfoBase(<Кластер>, <ИнформационнаяБаза>)Полное описание, параметры и ограничения
Соединение с агентом сервера.UpdateInfoBase (IServerAgentConnection.UpdateInfoBase)
Соединение с агентом сервера (IServerAgentConnection)
UpdateInfoBase (UpdateInfoBase)
Доступен, начиная с версии 8.1.
Синтаксис:
UpdateInfoBase(<Кластер>, <ИнформационнаяБаза>)
Параметры:
<Кластер> (обязательный)
Тип: Кластер серверов.
Кластер, в котором должны быть изменены параметры информационной базы.
<ИнформационнаяБаза> (обязательный)
Тип: Описание информационной базы.
Новое описание информационной базы. Изменено может быть только значение свойства Descr.
Описание:
Позволяет изменить параметры информационной базы, зарегистрированной в кластере. Изменять можно только словесное описание информационной базы.
Доступность:
Интеграция.
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Изменить только описание своей ИБ, прервать свой расчет и отдельно завершить свой UUID-сеанс
UpdateInfoBase разрешает только Descr. InterruptCurrentServerCall и TerminateSession получают оригинальный COM-сеанс, связанный со своими UUID кластера/ИБ/сеанса RAS, номером, пользователем и временем.
Где и как запускать
Полный серверный общий модуль УчебныйCOM85 и полный модуль управляемой формы в отдельной файловой учебной ИБ. Свой Windows-агент/RAS, точная платформа8.5.1.1343; перечисленные записи являются только авторским учебным кодом, фактических запусков0.
Подготовка
Работайте только в новой отдельной Windows-VM без рабочих процессов/кластеров. Установленная платформа и заранее зарегистрированный V85.COMConnector должны быть8.5.1.1343 соответствующей разрядности. Регистрацию COM и запуск служб этот BSL не выполняет.
Создайте отдельную файловую ИБ с именем конфигурации УчебныйЖизненныйЦиклCOM85: без данных, каталогов, документов, регистров, подписок, фоновых заданий и расширений. В ней создайте общий модуль УчебныйCOM85: Сервер=Истина, ВызовСервера=Истина, Глобальный=Ложь, Клиент/ВнешнееСоединение=Ложь. Вставьте полностью код одного урока, не смешивайте одинаковые функции разных уроков.
Создайте обработку и управляемую форму с командой Выполнить и полным модулем формы из дополнительного блока. Строковые реквизиты: Операция, ИмяАгента, ПарольАгента, ИмяАдминистратора, ПарольАдминистратора, UUIDОпыта, UUIDКластера, Дополнительно; числовые ПортАгента, ПортRAS, ПортКластера; булевый ПодтвержденСвойСтенд. Поля всех паролей и Дополнительно переведите в режим пароля, значения не сохраняйте в настройках.
В своей VM вручную поднимите один отдельный ragent и один ras с отдельным новым каталогом реестров. RAS должен обслуживать именно этот агент, а не другой локальный сервис. Из реально выбранных администратором свободных портов впишите три разные величины: agent-port для ConnectAgent, ras-port для АдминистрированиеСервера, manager-port для своего кластера. Не подставляйте1545 в ConnectAgent.
До первого создания кластера вручную удалите только автоматически созданный пустой кластер своей новой VM, если он появился. Консоль должна показывать0кластеров; никакие чужие кластеры не допускаются. Первый урок также проверяет нулевой список обоими интерфейсами до RegCluster.
Заведите постоянного своего администратора агента и после создания кластера постоянного своего администратора кластера через консоль. Их реальные новые учебные пароли передавайте форме; учебные временные администраторы в уроке никогда не заменяют постоянных.
Один раз самостоятельно получите UUIDОпыта в своей файловой ИБ выражением Строка(Новый УникальныйИдентификатор), сохраните текст в собственном журнале опыта. Имя кластера: own-com85-cluster-<UUIDОпыта>. После создания сохраните фактический RAS UUIDКластера из результата; имя не заменяет UUID.
Читающая команда Каталог85 не равна доказательству отсутствия production. Изоляция VM и новый реестр обязательны до любого подключения. COM не предоставляет UUID в интерфейсе IClusterInfo: пример сопоставляет его с прочитанным UUID RAS по sole-кластеру, точным loopback/имени/порту.
Запись/применение/отмена регистрации выполняются только отдельной явно выбранной строкой Операция. Не добавляйте автоматические повторы, очистку при исключении или откат чужого состояния. В случае частичного выполнения сохраните UUID и сначала прочитайте фактическое состояние.
Пароли очищаются из реквизитов и локальной структуры, но это не гарантирует стирания строк из памяти. Не выводите ОписаниеОшибки, строки подключения, Password или аргументы операций. Код статически проверяется здесь, но COM/RAS/1С, сеть и процессы не запускались.
Сначала bootstrap-урок подтверждает0кластеров, создает свой единственный кластер и подтверждает0ИБ. Сохраните оба UUID. Затем только вручную создайте в нем одну новую учебную серверную ИБ own-com85-base-<UUIDОпыта> на отдельно подготовленной учебной СУБД, без рабочих копий. Descr/Описание=owned-com85-lifecycle:<UUIDОпыта>, конфигурация УчебнаяЦельCOM85, пустая метадата без фоновых заданий и расширений. Создание ИБ/СУБД код не выполняет.
Фактический UUID ИБ из своей RAS-консоли впишите в JSON поле UUIDБазы. Разрешена только эта единственная ИБ, никаких чужих. Для ПометитьОписание85 закройте все ее целевые клиенты:0сеансов/0соединений. Код меняет только Descr на собственный маркер с суффиксом:checked.
В целевой ИБ создайте пользователя own-com85-user-<UUIDОпыта> с новым учебным паролем и нужными для пустой формы правами. Откройте только один прямой тонкий клиент этого пользователя. Конфигуратор и остальные целевые клиенты закройте. Управляющая форма работает в другой файловой ИБ.
В пустой целевой ИБ создайте обработку/форму с командами ПоказатьПаспорт и ДобровольныйРасчет. Реквизиты UUIDОпыта(Строка) и ПодтвержденУчебныйРасчет(Булево). Полностью вставьте дополнительный целевой модуль и свяжите команды с одноименными обработчиками.
В управляющей форме выполните Каталог85: фактические UUIDСеанса, Номер, ВремяНачала и AppID перенесите в тот же JSON. UUID, AppID и время — строки, номер — число. Номер не UUID и не уникален между ИБ.
Добровольно запустите ДобровольныйРасчет в целевом клиенте: ограниченный30секундами/100миллионами итераций арифметический расчет в памяти, без запросов, транзакций и файлов. Из управляющей файловой ИБ отдельно выберите ПрерватьСвойВызов85 во время расчета. Для ЗавершитьСвойСеанс85 отдельно подтвердите полное завершение этого учебного окна.
В этой фазе логично требуются отсутствие чужих ИБ и точный whitelist собственного UUID ИБ, а не0ИБ. После урока вручную закройте свои целевые процессы/сеансы; удаление своей ИБ модуль не выполняет.
Функция Выполнить85(Операция, Данные, Подтверждение) Экспорт
Если СтрРазделить("Каталог85,ПометитьОписание85,ПрерватьСвойВызов85,ЗавершитьСвойСеанс85", ",").Найти(Операция) = Неопределено Тогда
ВызватьИсключение "Неизвестная отдельная команда своей ИБ/сеанса";
КонецЕсли;
Связь = СоединитьсяСоСвоимАгентом85(Данные, Подтверждение);
Стенд = ПолучитьСвойКластер85(Связь, Данные, Истина);
Паспорт = ПрочитатьСвойJSON85(Данные.Дополнительно);
ПроверитьПоля85(Паспорт, "UUIDБазы");
ПроверитьUUID85(Паспорт.UUIDБазы);
СвояБазаRAS = Стенд.БазыRAS[0];
Если Строка(СвояБазаRAS.ИдентификаторИнформационнойБазы) <> Паспорт.UUIDБазы Тогда
ВызватьИсключение "Whitelist UUID единственной собственной учебной ИБ не совпал";
КонецЕсли;
СвояБазаCOM = Стенд.БазыCOM.Получить(0);
Если СвояБазаCOM.Name <> СвояБазаRAS.Имя Или СвояБазаCOM.Descr <> СвояБазаRAS.Описание Тогда
ВызватьИсключение "COM-описание не связано с фактическим UUID собственной ИБ";
КонецЕсли;
Если Операция = "ПометитьОписание85" Тогда
Если Связь.Агент.GetSessions(Стенд.COM).Количество() <> 0
Или Связь.Агент.GetConnections(Стенд.COM).Количество() <> 0 Тогда
ВызватьИсключение "Описание своей ИБ меняем только при0сеансов и0соединений";
КонецЕсли;
СвояБазаCOM.Descr = "owned-com85-lifecycle:" + Данные.UUIDОпыта + ":checked";
Связь.Агент.UpdateInfoBase(Стенд.COM, СвояБазаCOM);
После = ПолучитьСвойКластер85(Связь, Данные, Истина);
Если После.БазыCOM.Получить(0).Descr <> СвояБазаCOM.Descr
Или После.БазыRAS[0].Описание <> СвояБазаCOM.Descr
Или Строка(После.БазыRAS[0].ИдентификаторИнформационнойБазы) <> Паспорт.UUIDБазы Тогда
ВызватьИсключение "Изменение толькоDescr своей ИБ не подтверждено";
КонецЕсли;
Возврат "Изменено только словесное описание своей единственной UUID-ИБ; СУБД/профили/блокировки не менялись";
КонецЕсли;
ИмяПользователя = "own-com85-user-" + Данные.UUIDОпыта;
СеансыRAS = Стенд.RAS.ПолучитьСеансы();
Для Каждого Кандидат Из СеансыRAS Цикл
Если Строка(Кандидат.ИдентификаторИнформационнойБазы) <> Паспорт.UUIDБазы
Или Кандидат.ИмяПользователя <> ИмяПользователя Тогда
ВызватьИсключение "В whitelist-стенде появился другой пользователь/ИБ; любые воздействия запрещены";
КонецЕсли;
КонецЦикла;
Если СеансыRAS.Количество() > 1 Тогда
ВызватьИсключение "Разрешен только один добровольный собственный клиентский сеанс";
КонецЕсли;
СеансыCOM = Связь.Агент.GetInfoBaseSessions(Стенд.COM, СвояБазаCOM);
Если СеансыCOM.Количество() <> СеансыRAS.Количество() Тогда
ВызватьИсключение "Набор собственных сеансов изменился между RAS/COM-чтениями";
КонецЕсли;
Если Операция = "Каталог85" Тогда
Если СеансыRAS.Количество() = 0 Тогда
Возврат "Собственная UUID-ИБ подтверждена; сеансов0. Для прерывания/завершения откройте только свой отдельный целевой клиент";
КонецЕсли;
ЕдинственныйRAS = СеансыRAS[0];
ЕдинственныйCOM = СеансыCOM.Получить(0);
Если ЕдинственныйCOM.InfoBase.Name <> СвояБазаCOM.Name Или ЕдинственныйCOM.UserName <> ИмяПользователя
Или ЕдинственныйCOM.SessionID <> ЕдинственныйRAS.НомерСеанса
Или ЕдинственныйCOM.StartedAt <> ЕдинственныйRAS.ВремяНачала
Или ЕдинственныйCOM.AppID <> ЕдинственныйRAS.ИмяПриложения Тогда
ВызватьИсключение "Точное сопоставление UUID-сеанса с оригинальным COM-объектом не подтверждено";
КонецЕсли;
Возврат СтрШаблон("Собственный сеанс: UUIDСеанса=%1; Номер=%2; ВремяНачала=%3; AppID=%4",
Строка(ЕдинственныйRAS.ИдентификаторСеанса), ЕдинственныйCOM.SessionID,
XMLСтрока(ЕдинственныйCOM.StartedAt), ЕдинственныйCOM.AppID);
КонецЕсли;
ПроверитьПоля85(Паспорт, "UUIDСеанса,Номер,ВремяНачала,AppID");
ПроверитьUUID85(Паспорт.UUIDСеанса);
Если СеансыRAS.Количество() <> 1 Тогда
ВызватьИсключение "Собственный сеанс исчез; обновите каталог, не применяйте старый номер";
КонецЕсли;
СеансRAS = СеансыRAS[0];
Сеанс = СеансыCOM.Получить(0);
Если Строка(СеансRAS.ИдентификаторСеанса) <> Паспорт.UUIDСеанса
Или СеансRAS.НомерСеанса <> Паспорт.Номер Или Сеанс.SessionID <> Паспорт.Номер
Или XMLСтрока(СеансRAS.ВремяНачала) <> Паспорт.ВремяНачала
Или XMLСтрока(Сеанс.StartedAt) <> Паспорт.ВремяНачала
Или Сеанс.InfoBase.Name <> СвояБазаCOM.Name Или Сеанс.InfoBase.Descr <> СвояБазаCOM.Descr
Или Сеанс.UserName <> ИмяПользователя Или Сеанс.AppID <> Паспорт.AppID
Или СеансRAS.ИмяПриложения <> Паспорт.AppID Тогда
ВызватьИсключение "Own-UUID/пользователь/ИБ/номер/время/приложение изменились: воздействие запрещено";
КонецЕсли;
Если Операция = "ПрерватьСвойВызов85" Тогда
Если Сеанс.durationCurrent <= 0 Или СеансRAS.ДлительностьВызововТекущее <= 0 Тогда
Возврат "Текущего добровольного учебного вызова в снимке нет; прерывание не запрашивалось";
КонецЕсли;
Связь.Агент.InterruptCurrentServerCall(Стенд.COM, Сеанс, "Прерван только свой добровольный учебный расчетCOM85");
Возврат "Запрошено прерывание только own-вызова. В целевом клиенте проверьте остановку расчета; сеанс намеренно не завершался";
КонецЕсли;
Связь.Агент.TerminateSession(Стенд.COM, Сеанс, "Завершен только свой отдельный добровольный учебный сеансCOM85");
Для Каждого После Из Стенд.RAS.ПолучитьСеансы() Цикл
Если Строка(После.ИдентификаторСеанса) = Паспорт.UUIDСеанса Тогда
ВызватьИсключение "Own-UUID-сеанс пока остается: не повторяйте завершение автоматически";
КонецЕсли;
КонецЦикла;
Возврат "Own-UUID-сеанс отсутствует в повторном RAS-снимке. Откройте новый учебный сеанс только вручную и получите новый паспорт";
КонецФункции
Функция СоединитьсяСоСвоимАгентом85(Данные, Подтверждение)
ПроверитьСвойПустойСтенд();
Если ТипЗнч(Подтверждение) <> Тип("Булево") Или Не Подтверждение Тогда
ВызватьИсключение "Подтвердите отдельную собственную VM без рабочих кластеров";
КонецЕсли;
Для Каждого Поле Из СтрРазделить("ПортАгента,ПортRAS,ПортКластера", ",") Цикл
Порт = Данные[Поле];
Если ТипЗнч(Порт) <> Тип("Число") Тогда
ВызватьИсключение "Порт своего процесса должен быть числом";
КонецЕсли;
Если Порт < 1 Или Порт > 65535 Или Порт <> Цел(Порт) Тогда
ВызватьИсключение "Недопустимый фактический порт";
КонецЕсли;
КонецЦикла;
Если Данные.ПортАгента = Данные.ПортRAS Или Данные.ПортАгента = Данные.ПортКластера
Или Данные.ПортRAS = Данные.ПортКластера Тогда
ВызватьИсключение "Порты агента, менеджера кластера и ras различаются";
КонецЕсли;
Для Каждого Поле Из СтрРазделить("ИмяАгента,ПарольАгента,ИмяАдминистратора,ПарольАдминистратора,UUIDОпыта,UUIDКластера,Дополнительно", ",") Цикл
Если ТипЗнч(Данные[Поле]) <> Тип("Строка") Тогда
ВызватьИсключение "Имена, пароли и UUID должны быть строками";
КонецЕсли;
КонецЦикла;
ПроверитьUUID85(Данные.UUIDОпыта);
СерверRAS = Новый АдминистрированиеСервера("127.0.0.1", Данные.ПортRAS);
СерверRAS.ВыполнитьАутентификацию(Данные.ПарольАгента, Данные.ИмяАгента);
Если СерверRAS.ПолучитьВерсию() <> "8.5.1.1343" Тогда
ВызватьИсключение "RAS обязан обслуживать ровно собственный агент8.5.1.1343";
КонецЕсли;
Соединитель = Новый COMОбъект("V85.COMConnector");
Агент = Соединитель.ConnectAgent("127.0.0.1:" + Формат(Данные.ПортАгента, "ЧГ=0"));
Агент.AuthenticateAgent(Данные.ИмяАгента, Данные.ПарольАгента);
Возврат Новый Структура("Агент,RAS,Соединитель", Агент, СерверRAS, Соединитель);
КонецФункции
Процедура ПроверитьUUID85(UUID)
Проверенный = Новый УникальныйИдентификатор(UUID);
Если UUID <> Строка(Проверенный) Или UUID = "00000000-0000-0000-0000-000000000000" Тогда
ВызватьИсключение "Введите канонический собственный ненулевой UUID";
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСвойКластер85(Связь, Данные, РазрешенаСвояБаза = Ложь)
ПроверитьUUID85(Данные.UUIDКластера);
КластерыRAS = Связь.RAS.ПолучитьКластеры();
Если КластерыRAS.Количество() <> 1 Тогда
ВызватьИсключение "В агенте должен быть только один собственный кластер";
КонецЕсли;
КластерRAS = КластерыRAS[0];
ИмяКластера = "own-com85-cluster-" + Данные.UUIDОпыта;
Если Строка(КластерRAS.ИдентификаторКластера) <> Данные.UUIDКластера
Или КластерRAS.Имя <> ИмяКластера Или КластерRAS.Порт <> Данные.ПортКластера
Или КластерRAS.ИмяКомпьютера <> "127.0.0.1" Тогда
ВызватьИсключение "RAS UUID, имя, loopback или порт своего кластера не совпали";
КонецЕсли;
КластерRAS.ВыполнитьАутентификацию(Данные.ИмяАдминистратора, Данные.ПарольАдминистратора);
БазыRAS = КластерRAS.ПолучитьИнформационныеБазы();
Если Не РазрешенаСвояБаза И БазыRAS.Количество() <> 0 Тогда
ВызватьИсключение "Этот урок требует полностью пустой кластер";
КонецЕсли;
Если РазрешенаСвояБаза Тогда
Если БазыRAS.Количество() <> 1 Тогда
ВызватьИсключение "Разрешена только одна специально подготовленная собственная ИБ";
КонецЕсли;
Если БазыRAS[0].Имя <> "own-com85-base-" + Данные.UUIDОпыта
Или (БазыRAS[0].Описание <> "owned-com85-lifecycle:" + Данные.UUIDОпыта
И БазыRAS[0].Описание <> "owned-com85-lifecycle:" + Данные.UUIDОпыта + ":checked") Тогда
ВызватьИсключение "Чужая ИБ или неверный маркер собственного стенда";
КонецЕсли;
КонецЕсли;
КластерыCOM = Связь.Агент.GetClusters();
Если КластерыCOM.Количество() <> 1 Тогда
ВызватьИсключение "COM и RAS должны видеть один и тот же sole кластер";
КонецЕсли;
Кластер = КластерыCOM.Получить(0);
Если Кластер.ClusterName <> КластерRAS.Имя Или Кластер.HostName <> КластерRAS.ИмяКомпьютера
Или Кластер.MainPort <> КластерRAS.Порт Тогда
ВызватьИсключение "Нельзя сопоставить COM-описание с собственным RAS UUID";
КонецЕсли;
Связь.Агент.Authenticate(Кластер, Данные.ИмяАдминистратора, Данные.ПарольАдминистратора);
БазыCOM = Связь.Агент.GetInfoBases(Кластер);
Если БазыCOM.Количество() <> БазыRAS.Количество() Тогда
ВызватьИсключение "Состояние собственных ИБ изменилось между чтениями";
КонецЕсли;
Основных = 0;
Вторичных = 0;
Для Каждого Рабочий Из КластерRAS.ПолучитьРабочиеСерверы() Цикл
Если Рабочий.ИмяКомпьютера <> "127.0.0.1" Тогда
ВызватьИсключение "В своём UUID-кластере появился нелокальный рабочий сервер";
КонецЕсли;
Если Рабочий.ЦентральныйСервер И Рабочий.Порт = Данные.ПортАгента Тогда
Основных = Основных + 1;
ИначеЕсли Не Рабочий.ЦентральныйСервер И Рабочий.Имя = "own-com85-worker-" + Данные.UUIDОпыта
И Рабочий.Порт <> Данные.ПортАгента Тогда
Вторичных = Вторичных + 1;
Иначе
ВызватьИсключение "Разрешены только собственные основной и UUID-вторичный рабочие серверы";
КонецЕсли;
КонецЦикла;
Если Основных <> 1 Или Вторичных > 1 Тогда
ВызватьИсключение "Own-топология рабочего стенда изменилась";
КонецЕсли;
Возврат Новый Структура("COM,RAS,БазыCOM,БазыRAS", Кластер, КластерRAS, БазыCOM, БазыRAS);
КонецФункции
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
Функция ПрочитатьСвойJSON85(Текст)
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Текст);
Попытка
Значение = ПрочитатьJSON(Чтение);
Исключение
Чтение.Закрыть();
ВызватьИсключение "Некорректный собственный JSON-паспорт";
КонецПопытки;
Чтение.Закрыть();
Если ТипЗнч(Значение) <> Тип("Структура") Тогда
ВызватьИсключение "Собственный JSON должен содержать объект";
КонецЕсли;
Возврат Значение;
КонецФункции
Процедура ПроверитьПоля85(Данные, Поля)
Для Каждого Поле Из СтрРазделить(Поля, ",") Цикл
Если Не Данные.Свойство(Поле) Тогда
ВызватьИсключение "Заполните фактическое собственное поле " + Поле;
КонецЕсли;
КонецЦикла;
КонецПроцедурыМодуль управляемой формы обработки: команда Выполнить
Обработка.УчебныйCOM85.Форма.Форма: полный модуль формы
Клиентский/серверный модуль управляемой формы отдельной файловой ИБ; процедуры уже содержат директивы. Поля созданы согласно подготовке.
&НаКлиенте
Процедура Выполнить(Команда)
Данные = Новый Структура;
Данные.Вставить("ПортАгента", ПортАгента);
Данные.Вставить("ПортRAS", ПортRAS);
Данные.Вставить("ПортКластера", ПортКластера);
Данные.Вставить("ИмяАгента", ИмяАгента);
Данные.Вставить("ПарольАгента", ПарольАгента);
Данные.Вставить("ИмяАдминистратора", ИмяАдминистратора);
Данные.Вставить("ПарольАдминистратора", ПарольАдминистратора);
Данные.Вставить("UUIDОпыта", UUIDОпыта);
Данные.Вставить("UUIDКластера", UUIDКластера);
Данные.Вставить("Дополнительно", Дополнительно);
ПарольАгента = "";
ПарольАдминистратора = "";
Дополнительно = "";
Попытка
Ответ = ВыполнитьНаСервере(Операция, Данные, ПодтвержденСвойСтенд);
Исключение
Данные.ПарольАгента = "";
Данные.ПарольАдминистратора = "";
Данные.Дополнительно = "";
Сообщить("Операция не подтверждена. Не повторяйте запись автоматически. Проверьте только свой изолированный стенд и ранее записанные UUID.");
Возврат;
КонецПопытки;
Данные.ПарольАгента = "";
Данные.ПарольАдминистратора = "";
Данные.Дополнительно = "";
Сообщить(Ответ);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ВыполнитьНаСервере(Операция, Данные, ПодтвержденСвойСтенд)
Возврат УчебныйCOM85.Выполнить85(Операция, Данные, ПодтвержденСвойСтенд);
КонецФункцииПолный модуль формы отдельной собственной целевой ИБ УчебнаяЦельCOM85
УчебнаяЦельCOM85: полный модуль собственной управляемой формы
Полный клиентский/серверный модуль управляемой формы собственной пустой целевой ИБ УчебнаяЦельCOM85. Только добровольный отдельный целевой пользователь; арифметический расчет ограничен30секундами.
&НаКлиенте
Процедура ПоказатьПаспорт(Команда)
Сообщить(ПолучитьПаспортНаСервере(UUIDОпыта));
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьПаспортНаСервере(UUIDОпыта)
ПроверитьУчебнуюЦель85(UUIDОпыта);
Возврат СтрШаблон("Own-пользователь=%1; номер текущего собственного сеанса=%2",
ИмяПользователя(), НомерСеансаИнформационнойБазы());
КонецФункции
&НаКлиенте
Процедура ДобровольныйРасчет(Команда)
Попытка
Ответ = РассчитатьНаСервере(UUIDОпыта, ПодтвержденУчебныйРасчет);
Исключение
Сообщить("Собственный расчет остановлен либо свой сеанс завершен. Если ожидали прерывание, проверьте новый каталог и паспорт");
Возврат;
КонецПопытки;
Сообщить(Ответ);
КонецПроцедуры
&НаСервереБезКонтекста
Функция РассчитатьНаСервере(UUIDОпыта, Подтверждение)
ПроверитьУчебнуюЦель85(UUIDОпыта);
Если ТипЗнч(Подтверждение) <> Тип("Булево") Или Не Подтверждение Тогда
ВызватьИсключение "Расчет добровольно запускается только на своей пустой VM";
КонецЕсли;
КонецВремени = ТекущаяУниверсальнаяДата() + 30;
Итераций = 0;
Сумма = 0;
Пока ТекущаяУниверсальнаяДата() < КонецВремени И Итераций < 100000000 Цикл
Сумма = Сумма + Итераций % 97;
Итераций = Итераций + 1;
КонецЦикла;
Возврат СтрШаблон("Свой расчет завершился естественно: итераций=%1; сумма=%2. Прерывание не гарантируется после завершения", Итераций, Сумма);
КонецФункции
&НаСервереБезКонтекста
Процедура ПроверитьУчебнуюЦель85(UUIDОпыта)
ПроверитьСвойПустойСтенд();
Проверенный = Новый УникальныйИдентификатор(UUIDОпыта);
Если Строка(Проверенный) <> UUIDОпыта Или UUIDОпыта = "00000000-0000-0000-0000-000000000000"
Или ИмяПользователя() <> "own-com85-user-" + UUIDОпыта Тогда
ВызватьИсключение "Только свой фактический пользователь учебной цели";
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыРазбор по шагам
СоединитьсяСоСвоимАгентом85 проверяет точную платформу, новую пустую конфигурацию и явное подтверждение VM; только затем создает свои два административных подключения.
RAS выполняет проверку точной версии обслуживаемого агента. COM и RAS получают разные порты; COM AuthenticateAgent принимает имя, затем пароль, тогда как RAS ВыполнитьАутентификацию принимает пароль, затем имя.
ПолучитьСвойКластер85 принимает только один кластер: собственный UUID, имя с UUIDОпыта, loopback127.0.0.1 и фактический порт. UUID берется из RAS, не выдумывается как свойство COM-кластера.
До операции повторно проверяется допустимый набор ИБ; по умолчанию0. Постоянная кластерная аутентификация отделена от агентской и не заменяется учетными данными временного создаваемого объекта.
RAS UUID, имя и маркер подтверждают единственную собственную ИБ. Короткое COM-описание имеет Name/Descr, не UUID; сопоставление идет через свою единственную UUID-ИБ RAS.
ПометитьОписание85 получает оригинальное описание COM, меняет только Descr, вызывает UpdateInfoBase. Повторные COM/RAS-чтения проверяют Descr и прежний UUID ИБ. dbPassword, Name, СУБД и блокировки не меняются.
Каталог допускает0или1сеанс своего пользователя, никаких чужих. Каждый оригинальный COM-сеанс проверяется по времени старта, номеру и AppID против точного UUID RAS.
Прерывающая команда повторно проверяет UUIDСеанса, UUIDИБ, пользователя, номер, StartedAt, AppID и текущий вызов. Если расчет уже закончился, ничего не прерывается, и это не ошибка.
InterruptCurrentServerCall не TerminateSession: запрашивается прерывание вызова, целевой клиент обрабатывает ошибку, а сеанс может остаться. Конкретный результат оператор проверяет в целевом клиенте.
ЗавершитьСвойСеанс85 отдельно вызывает TerminateSession для одного оригинального COM-объекта. Его UUID должен отсутствовать в повторном RAS-списке. Новый сеанс требует новый паспорт.
Как проверить результат
Вторая ИБ, другой пользователь/UUID/номер или новое время старта запрещают изменения.
UpdateInfoBase меняет только Descr; собственный UUID ИБ не изменился, на этот момент0сеансов/0соединений.
При прерывании расчета клиент получает ошибку, но сеанс намеренно не завершается. Если вызов закончился, код сообщает отсутствие.
После отдельного завершения UUIDСеанса отсутствует; своя ИБ не удалена, новый вход получает новый паспорт.
Ожидаемый результат
Освоены одноцелевое изменение Descr, прерывание отдельного вызова и завершение своего сеанса; production и чужие пользователи не затронуты.
На что обратить внимание
Это будущий ручной учебный запуск на собственной VM, а не уже выполненная операция. runtimeVerifiedScenarios остается0; статические проверки не гарантируют COM-регистрацию, лицензии или успешный ответ агента.
Проверки выполняются перед вызовами, но не образуют распределенную транзакцию и не исключают гонку. Только один оператор может менять стенд; при любом несоответствии остановитесь.
Не используйте production, копию рабочего реестра или имена чужих пользователей. Нельзя расширять разрешения рабочей базы ради COM-подключения.
Реальный самостоятельный запуск нужен только по отдельному добровольному учебному плану; здесь не запускался даже целевой расчет.
Запрос прерывания не доказывает немедленную отмену всех операций. В уроке нет DBwrites/транзакций; нельзя проверять им восстановление рабочих документов.
Контроллер работает в другой файловой ИБ. Запрещены массовые прерывания/завершения; цель выбирается по UUID, а не первому элементу чужого списка.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.