Змяненне настроек праграм з захаваннем персанальных параметраў

перадгісторыя

У адной медыцынскай арганізацыі ўкаранялі рашэнні на базе PACS-сервераў Orthanc і DICOM-кліента Radiant. У ходзе наладкі высветлілі, што кожны DICOM-кліент павінен быць апісаны ў PACS-серверах наступным чынам:

  • Імя кліента
  • AE-імя (павінна быць унікальна)
  • TCP-порт, які аўтаматычна адчыняецца на боку кліента і прымае DICOM-абследаванні ад PACS-сервера (г.зн. сервер як бы штурхае іх у бок кліента – ініцыюючы злучэнне першым)
  • IP-адрас

Пасля настройкі Radiant кліентаў атрымалі наступную інфармацыю да разважання – у кожнага кліента настройка ПЗ з названымі вышэй параметрамі прыводзіла да запаўнення файла pacs.xml, які размяшчаўся ў профілі карыстальніка (шлях: %APPDATA%RadiantViewerpacs.xml). Пры гэтым канфіг аднаго кліента ад іншага адрозніваўся мінімум двума параметрамі (AE-імя ва ўсіх рознае, а порт у асноўным аднолькавы, акрамя тэрмінальных кліентаў, якія працуюць на адным і тым жа серверы - тамака парты таксама прыходзілася прызначаць рознымі).

Прыклад файла pacs.xml па спасылцы:

Прыкладна паўгода ўсё было добра, сістэма зарабіла…і тут да нас дайшліпадводныя камяні»:

  • Нам трэба ўвесці ў строй некалькі новых PACS-сервераў, якія падменяць старыя (дзе стала сканчацца месца на кружэлках). PACS сервера ў віртуальных машынах, але гаворка не пра гэта;
  • Нам трэба неяк цэнтралізавана змяніць унікальныя канфігурацыі (двума адрознымі параметрамі) на 200 машынах (іх колькасць рэгулярна павялічвалася);
  • Улічваючы тэмпы росту аб'ёмаў абследаванняў, рашэнне трэба не разавае, а якое тыражуецца і рэгулярнае (напрыклад, 1 раз у 3-5 месяцаў).

Рашэнне ніжэй.

Выбар інструментара для рашэння задачы

Спачатку былі спробы знайсці нейкае рашэнне, якое на баку кліента змяняла файл pacs.xml, і ўносіла ў яго змены ў спіс PACS-сервераў, не чапаючы налады AE-імя і TCP-порта. Windows кліенты на той момант былі на базе як Windows XP, так і Windows 7 - таму былі спробы напісаць нешта такое на базе VBScript. Але нажаль – здужаць такую ​​задачу не атрымалася, з прычыны поўнай адсутнасці досведу напісання чагосьці складанага і комплекснага на гэтай мове. Спробы ж знайсці і перапісаць таксама не ўвянчаліся поспехам (тут трэба адзначыць, што ў галаве ўжо быў іншы план, таму я не дзяўбіўся з VBScript больш 3-4 гадзін).

У выніку я спыніўся на наступным рашэнні:

  • Сабраць групавой палітыкай усе файлы pacs.xml у адным месцы на якім ні будзь серверы ў сеткавым рэсурсе;
  • Змяніць файлы гуртам (досвед рашэння такіх задач ужо быў – з выкарыстаннем Perl);
  • Таксама з дапамогай групавых палітык абнавіць наладкі кліентаў.

Збор файлаў з дапамогай групавой палітыкі

Самая простая частка - пры ўваходзе кліента ў свой профіль ён са сваімі правамі выконвае нейкі .bat файл, у якім прапісана:

echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml

Такім чынам на серверы ва ўтоеным рэсурсе будуць назапашвацца файлы pacs.xml, у імі якіх ёсць інфармацыя з якога кампутара і з якога карыстача быў скапіяваны дадзены канфіг.

Самае складанае было - дачакацца, калі ва ўсіх карыстальнікаў адпрацуе дадзеная палітыка.

Змяненне канфігурацый з дапамогай Perl скрыпту

Нам спатрэбіцца Active Perl пад Windows ад кампаніі ActiveState, а таксама модуль XML::Writer, які можна ўсталяваць з дапамогай каманды ppm install XML-Writer.

Сам жа скрыпт атрымаўся даволі просты.

use XML::Writer;
 
# Открываем папку с отчетами, обрабатываем ссписок (удаляем лишнее):
	$report_dir = "C:Perl64WORKPACS-xml3";
	opendir(DIR, "$report_dir") or die "Не могу открыть папку с отчетами!";
	@report_files = readdir DIR;
	shift (@report_files); # удаляем точку из элементов массива (.)
	shift (@report_files); # удаляем две точки из элементов массива (..)
#	print "@report_files";
	closedir(DIR);
 
# Начинаем обрабатывать файлы - по одному за раз. Нужно считать параметр AET и номер порта в переменные.
foreach $analiz_file (@report_files) 
{
	$full_path_to_file="C:Perl64WORKPACS-xml3".$analiz_file;
	open (INFO, $full_path_to_file);
 
	while ($line = <INFO>)
	{
		# Переменные $aet и $port содержат уникальные данные для каждого XML файла:
		my ($other1, $aet, $other2, $port, $other3) = split /"/, $line, 5;
		# Если встречается строка listener - то мы дошли до нужной строчки и можно формировать новый XML:
		if ($other1 =~ 'listener')
			{
				# Формируем новый XML c нужными полями и данными:
				my $writer = XML::Writer->new(OUTPUT => 'self', DATA_MODE => 1, DATA_INDENT => 2, );
				$writer->xmlDecl('utf-8');
				$writer->startTag('pacs');
				$writer->startTag('listener', ae => $aet, port => $port);
				$writer->endTag();
				$writer->startTag('hosts');
				$writer->startTag('host', name => 'MRT', ae => 'ORTHANC', ip => 'XX.YY.214.17', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'KT', ae => 'ORTHANC2', ip => 'XX.YY.215.253', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'R', ae => 'ORTHANC3', ip => 'XX.YY.215.252', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'KT-20180501-20180831', ae => 'ORTHANC4', ip => 'XX.YY.215.251', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->startTag('host', name => 'KT-20180901-20181130', ae => 'ORTHANC5', ip => 'XX.YY.215.250', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0');
				$writer->endTag();
				$writer->endTag('hosts');
				$writer->startTag('presets');
				$writer->endTag();
				$writer->startTag('lastsearch', dt => '4', mfid => '1048592');
				$writer->endTag();
				$writer->endTag('pacs');
 
				# Помещаем готовый XML в переменную:
				my $xml = $writer->end();
				# Подготавливаем файл для перезаписи:
				$rewritexml = $full_path_to_file;
				# Переписываем XML файлы новыми данными:
				open (NEWXML, ">$rewritexml");
				print NEWXML $xml;
				close (NEWXML);				
			}
	}
 
}

Прынцып яго працы:

  • Адкрываем каталог, у якім у нас сабраны канфігурацыі pacs.xml ад кліентаў і змяшчаем спіс файлаў у масіў скаляраў (@report_files);
  • У цыкле апрацоўваем па адным файле і счытваем яго парадкова;
  • З дапамогай split дробім кожны радок на 5 частак, выкарыстоўваючы двукоссі як падзельнік;
  • Знаходзім радок са словам listener і змяшчаем у дзве зменныя ўнікальныя для кожнага файла дадзеныя (AE-імя кліента і нумар TCP-порта);
  • Пасля гэтага проста фармуем новы XML-файл, упісваем у яго ўнікальныя параметры і далей устаўляем патрэбную колькасць PACS-сервераў з іх параметрамі – г.зн. тое, дзеля чаго ўсё ладзілася)
  • Перапісваем новы XML-файл па-над старым.

Трэба адзначыць, што насамрэч я выкарыстоўваю дадзены скрыпт не цалкам аўтаматычна – у сутнасці я капіюю збіраныя канфігі ў асобны каталог і потым запускаючы скрыпт змяняю іх усім гуртам. Далей выбарачная праверка і канфігі можна разліваць зваротна па машынах.

Распаўсюджванне змененых pacs.xml файлаў па кліентах

Самае простае, што прыйшло ў галаву - унесці змены ва ўжо які працуе .bat файл, які збірае канфігурацыі з кліентаў і дадаць радок:

If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Выніковы .bat файл выглядае так:

@echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml
If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Заключэнне

Такое вось «накаленкавы» рашэнне. Выпрабавалі яго ўжо два разы (у верасні 2018 і ў лютым 2019), пакуль палёт нармальны. Вядома абнаўляе не 100% кліентаў, але блізка да гэтага значэння - астатніх дарабляем выдалена. Скрыпт па спасылцы.

Крыніца: habr.com

Дадаць каментар