Задание выгрузка. Регламентное задание МиграцияПриложенийВыгрузка.
// Регламентное задание МиграцияПриложенийВыгрузка.
//
Процедура ЗаданиеВыгрузка(ЗавершитьМиграцию = Ложь) Экспорт
ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.МиграцияПриложенийВыгрузка);
УстановитьПривилегированныйРежим(Истина);
СостояниеВыгрузки = РегистрыСведений.МиграцияПриложенийСостояниеВыгрузки.СоздатьМенеджерЗаписи();
СостояниеВыгрузки.Прочитать();
Если Не СостояниеВыгрузки.Выбран() Тогда
ПредставлениеОшибки = НСтр("ru = 'Состояние выгрузки не найдено.'");
РегистрацияОшибки(НСтр("ru = 'Выгрузка'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()), ПредставлениеОшибки);
РегламентныеЗаданияСервер.УдалитьЗадание(Метаданные.РегламентныеЗадания.МиграцияПриложенийВыгрузка);
Возврат;
КонецЕсли;
УзелОбмена = СостояниеВыгрузки.УзелОбмена;
Если Не ЗначениеЗаполнено(УзелОбмена) Тогда
ПредставлениеОшибки = НСтр("ru = 'Не найден узел обмена.'");
ЗавершитьВыгрузкуСОшибкой(СостояниеВыгрузки, ПредставлениеОшибки, ПредставлениеОшибки);
Возврат;
КонецЕсли;
Попытка
ЗаблокироватьДанныеДляРедактирования(УзелОбмена);
КлючЗаписи = РегистрыСведений.МиграцияПриложенийСостояниеВыгрузки.СоздатьКлючЗаписи(Новый Структура);
ЗаблокироватьДанныеДляРедактирования(КлючЗаписи);
Исключение
Возврат;
КонецПопытки;
// Регистрация объектов идет до обращения к сервису, т.к. приложение может быть еще не готово.
Если СостояниеВыгрузки.НомерОтправленногоСообщения = 0 Тогда
Для Каждого КлючИЗначение Из МиграцияПриложенийПовтИсп.ВыгружаемыеОбъекты() Цикл
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, КлючИЗначение.Ключ);
Если Метаданные.РегистрыРасчета.Содержит(КлючИЗначение.Ключ) Тогда
Для Каждого Перерасчет Из КлючИЗначение.Ключ.Перерасчеты Цикл
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Перерасчет);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
ПараметрыДоступа = ИнтеграцияПодсистемБТС.ПрочитатьДанныеИзБезопасногоХранилища(УзелОбмена, "ПараметрыДоступа");
УстановитьПривилегированныйРежим(Ложь);
Если ПараметрыДоступа = Неопределено Тогда
ПредставлениеОшибки = НСтр("ru = 'Не найдены параметры подключения.'");
ЗавершитьВыгрузкуСОшибкой(СостояниеВыгрузки, ПредставлениеОшибки, ПредставлениеОшибки);
Возврат;
КонецЕсли;
Попытка
СостояниеЗагрузки = СостояниеЗагрузкиИзСервиса(ПараметрыДоступа);
Исключение
// Сервис может быть недоступен, это не ошибка.
ПредставлениеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
Шаблон = НСтр("ru = 'Не удалось получить состояние загрузки, возможно сервис временно недоступен: %1 %1'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка());
Комментарий = СтрШаблон(Шаблон, Символы.ПС, ПредставлениеОшибки);
РегистрацияПримечания(НСтр("ru = 'Выгрузка'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()), Комментарий);
ДатаПроверки = ?(ЗначениеЗаполнено(СостояниеВыгрузки.ДатаСостоянияЗагрузки), СостояниеВыгрузки.ДатаСостоянияЗагрузки, СостояниеВыгрузки.ДатаНачала);
Если (ТекущаяУниверсальнаяДата() - ДатаПроверки) > (86400) Тогда
ПредставлениеОшибки = НСтр("ru = 'Сервис недоступен 24 часа, выгрузка прервана.'");
ЗавершитьВыгрузкуСОшибкой(СостояниеВыгрузки, ПредставлениеОшибки, ПредставлениеОшибки);
КонецЕсли;
Возврат;
КонецПопытки;
Если СостояниеЗагрузки.ИмяКонфигурации <> Метаданные.Имя Тогда
ПредставлениеОшибки = НСтр("ru = 'Имя конфигурации не совпадает.'");
ЗавершитьВыгрузкуСОшибкой(СостояниеВыгрузки, ПредставлениеОшибки, ПредставлениеОшибки);
КонецЕсли;
Если СостояниеВыгрузки.НомерПринятогоСообщения < СостояниеЗагрузки.НомерПринятогоСообщения Тогда
СостояниеВыгрузки.НомерПринятогоСообщения = СостояниеЗагрузки.НомерПринятогоСообщения;
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, СостояниеЗагрузки.НомерПринятогоСообщения);
КонецЕсли;
Если СостояниеЗагрузки.ТребуетсяПовторнаяОтправка Тогда
// Значит версия в приемнике обновилась и нужно повторно отправить уже выгруженные объекты.
ЗарегистрироватьИзмененияПовторно(УзелОбмена, СостояниеВыгрузки.НомерОтправленногоСообщения);
НачатьТранзакцию();
Попытка
// В приемнике очередь очищена, здесь тоже нужно сбросить номер отправленного
СостояниеВыгрузки.НомерОтправленногоСообщения = СостояниеЗагрузки.НомерПринятогоСообщения;
СостояниеЗагрузки = ПодтвердитьПовторнуюЗагрузкуВСервисе(ПараметрыДоступа);
ЗаполнитьСостояниеВыгрузки(СостояниеВыгрузки, СостояниеЗагрузки, УзелОбмена);
СостояниеВыгрузки.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецЕсли;
Если СостояниеЗагрузки.ВерсияКонфигурации <> Метаданные.Версия Тогда
СостояниеВыгрузки.Состояние = Перечисления.СостоянияМиграцииПриложения.ОжиданиеОбновления;
СостояниеВыгрузки.Комментарий = СостояниеЗагрузки.ВерсияКонфигурации;
ЗаполнитьСостояниеВыгрузки(СостояниеВыгрузки, СостояниеЗагрузки, УзелОбмена);
СостояниеВыгрузки.Записать();
ИначеЕсли СостояниеВыгрузки.Состояние = Перечисления.СостоянияМиграцииПриложения.ОжиданиеОбновления Тогда
СостояниеВыгрузки.Состояние = Перечисления.СостоянияМиграцииПриложения.Выполняется;
СостояниеВыгрузки.Записать();
Возврат;
КонецЕсли;
НомерСообщения = СостояниеВыгрузки.НомерОтправленногоСообщения + 1;
Если (СостояниеВыгрузки.НомерОтправленногоСообщения - СостояниеЗагрузки.НомерПринятогоСообщения) >= МаксимальнаяОчередьЗагрузки() Тогда
ЗаполнитьСостояниеВыгрузки(СостояниеВыгрузки, СостояниеЗагрузки, УзелОбмена);
СостояниеВыгрузки.Записать();
Возврат;
ИначеЕсли СостояниеЗагрузки.ЗавершеноСОшибками Тогда
ЗаполнитьСостояниеВыгрузки(СостояниеВыгрузки, СостояниеЗагрузки, УзелОбмена);
СостояниеВыгрузки.ДатаЗавершения = ТекущаяУниверсальнаяДата();
РегламентныеЗаданияСервер.УдалитьЗадание(Метаданные.РегламентныеЗадания.МиграцияПриложенийВыгрузка);
УзелОбмена.ПолучитьОбъект().Удалить();
СостояниеВыгрузки.Записать();
Возврат;
ИначеЕсли СостояниеВыгрузки.Состояние = Перечисления.СостоянияМиграцииПриложения.ОжиданиеЗагрузки Тогда
// Сообщения больше не формируются, а только ожидается когда все будет загружено.
НачатьТранзакцию();
Попытка
Если Не СостояниеЗагрузки.ВыполняетсяЗагрузка Тогда
СостояниеВыгрузки.ДатаЗавершения = ТекущаяУниверсальнаяДата();
СостояниеВыгрузки.Состояние = Перечисления.СостоянияМиграцииПриложения.ЗавершенаУспешно;
СостояниеВыгрузки.Комментарий = НСтр("ru = 'Переход завершен.'");
СостояниеВыгрузки.УзелОбмена = Неопределено;
РегламентныеЗаданияСервер.УдалитьЗадание(Метаданные.РегламентныеЗадания.МиграцияПриложенийВыгрузка);
УзелОбмена.ПолучитьОбъект().Удалить();
КонецЕсли;
ЗаполнитьСостояниеВыгрузки(СостояниеВыгрузки, СостояниеЗагрузки, УзелОбмена);
СостояниеВыгрузки.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Возврат;
КонецЕсли;
КаталогВыгрузки = ПолучитьИмяВременногоФайла("AppMigrationOut") + ПолучитьРазделительПути();
СоздатьКаталог(КаталогВыгрузки);
НачатьТранзакцию();
Попытка
Результат = ВыгрузитьДанныеВКаталог(КаталогВыгрузки,
УзелОбмена,
НомерСообщения,
СостояниеВыгрузки.ПоследнийОбъектМетаданных,
СостояниеВыгрузки.ВыгружатьНастройкиПользователей.Получить(),
СостояниеВыгрузки.ЗавершитьМиграциюАвтоматически Или ЗавершитьМиграцию);
Исключение
ОтменитьТранзакцию();
ИнформацияОбОшибке = ИнформацияОбОшибке();
СостояниеВыгрузки.КоличествоПопыток = СостояниеВыгрузки.КоличествоПопыток + 1;
СостояниеВыгрузки.ДатаПоследнейВыгрузки = ТекущаяУниверсальнаяДата();
ЗаполнитьСостояниеВыгрузки(СостояниеВыгрузки, СостояниеЗагрузки, УзелОбмена);
Если СостояниеВыгрузки.КоличествоПопыток >= 3 Тогда
ЗавершитьВыгрузкуСОшибкой(СостояниеВыгрузки, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке), КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
Иначе
СостояниеВыгрузки.Комментарий = КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
СостояниеВыгрузки.Записать();
РегистрацияОшибки(НСтр("ru = 'Выгрузка'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()), ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
КонецЕсли;
Возврат;
КонецПопытки;
Попытка
// Сообщение отправляется только если в нем есть данные.
Если Результат.КоличествоОбъектов > 0 Или Результат.ЭтоПоследнееСообщение Тогда
ИмяФайлаАрхива = ПолучитьИмяВременногоФайла("zip");
ЗаписьZIP = Новый ЗаписьZipФайла(ИмяФайлаАрхива);
ЗаписьZIP.Добавить(КаталогВыгрузки + "*", РежимСохраненияПутейZIP.СохранятьОтносительныеПути, РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно);
ЗаписьZIP.Записать();
СостояниеВыгрузки.НомерОтправленногоСообщения = НомерСообщения;
СостояниеВыгрузки.ВыгруженоОбъектов = СостояниеВыгрузки.ВыгруженоОбъектов + Результат.КоличествоОбъектов;
СостояниеВыгрузки.КоличествоПопыток = 0;
СостояниеВыгрузки.ДатаПоследнейВыгрузки = ТекущаяУниверсальнаяДата();
СостояниеВыгрузки.Комментарий = "";
Если Результат.ЭтоПоследнееСообщение Тогда
СостояниеВыгрузки.Состояние = Перечисления.СостоянияМиграцииПриложения.ОжиданиеЗагрузки;
КонецЕсли;
СостояниеВыгрузки.Записать();
СостояниеЗагрузки = ОтправитьСообщениеВСервис(ПараметрыДоступа, ИмяФайлаАрхива);
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ЗаполнитьСостояниеВыгрузки(СостояниеВыгрузки, СостояниеЗагрузки, УзелОбмена);
СостояниеВыгрузки.Записать();
Попытка
УдалитьФайлы(ИмяФайлаАрхива);
Исключение
ПредставлениеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
РегистрацияОшибки(НСтр("ru = 'Выгрузка'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()), ПредставлениеОшибки);
КонецПопытки;
Попытка
УдалитьФайлы(КаталогВыгрузки);
Исключение
ПредставлениеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
РегистрацияОшибки(НСтр("ru = 'Выгрузка'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()), ПредставлениеОшибки);
КонецПопытки;
КонецПроцедуры
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
ЭкспортОценкиПроизводительности (БСП)
НаименованиеФоновогоРезервногоКопирования (БСП)
Канал FastCode 1C в Телеграм! Шаблоны кода, статьи, полезные советы, курсы по 1С (8К участников)