forhistorie
En medisinsk organisasjon implementerte løsninger basert på Orthanc PACS-servere og Radiant DICOM-klient. Under oppsettet fant vi ut at hver DICOM-klient må beskrives i PACS-servere som følger:
- Klientens navn
- AE-navn (må være unikt)
- En TCP-port som automatisk åpnes på klientsiden og mottar DICOM-undersøkelser fra PACS-serveren (dvs. serveren skyver dem mot klienten - starter tilkoblingen først)
- IP-adresse
Etter å ha satt opp Radiant, fikk kundene følgende tankevekkende: For hver klient resulterte oppsett av programvaren med parametrene ovenfor i at filen ble fylt ut pacs.xml, som var plassert i brukerprofilen (bane: %APPDATA%RadiantViewerpacs.xml). Samtidig skilte konfigurasjonen til en klient seg fra en annen i minst to parametere (AE-navnet er forskjellig for alle, og porten er i utgangspunktet den samme, bortsett fra terminalklienter som kjører på samme server - der hadde portene også skal tildeles annerledes).
Eksempel pacs.xml-fil av
I omtrent seks måneder var alt bra, systemet begynte å fungere ... og så kom det til oss "undervanns steiner'
- Vi må sette i drift flere nye PACS-servere som skal erstatte de gamle (hvor diskplass har begynt å gå tom). PACS-servere i virtuelle maskiner, men det er ikke det vi snakker om;
- Vi må på en eller annen måte sentralt endre unike konfigurasjoner (med to forskjellige parametere) på 200 maskiner (antallet deres økte jevnlig);
- Med tanke på veksthastigheten for undersøkelsesvolumer, er det nødvendig med en løsning, ikke bare én gang, men replikert og regelmessig (for eksempel én gang hver 1.-3. måned).
Velge verktøy for å løse et problem
Til å begynne med var det forsøk på å finne en løsning som ville endre pacs.xml-filen på klientsiden og gjøre endringer i listen over PACS-servere uten å påvirke AE-navnet og TCP-portinnstillingene. Windows-klienter på den tiden var basert på både Windows XP og Windows 7 - så det var forsøk på å skrive noe slikt basert på VBScript. Men dessverre, det var ikke mulig å mestre en slik oppgave, på grunn av den fullstendige mangelen på erfaring med å skrive noe komplekst og komplekst på dette språket. Forsøk på å finne og omskrive var også mislykket (det skal bemerkes at jeg allerede hadde en annen plan i hodet mitt, så jeg fiklet ikke med VBScript på mer enn 3-4 timer).
Til slutt bestemte jeg meg for følgende løsning:
- Ved å bruke gruppepolicy, samle alle pacs.xml-filer på ett sted på en hvilken som helst server i en nettverksressurs;
- Endre filer massevis (jeg hadde allerede erfaring med å løse slike problemer ved å bruke Perl);
- Bruk også gruppepolicyer for å oppdatere klientinnstillinger.
Samle filer ved hjelp av gruppepolicy
Den enkleste delen er at når en klient logger på profilen sin, kjører han, med sine rettigheter, en viss .bat-fil, som sier:
echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml
Dermed vil pacs.xml-filer samle seg på serveren i en skjult ressurs, hvis navn inneholder informasjon fra hvilken datamaskin og fra hvilken bruker denne konfigurasjonen ble kopiert.
Det vanskeligste var å vente til denne policyen fungerte for alle brukere.
Endre konfigurasjoner ved hjelp av et Perl-skript
Vi trenger
Selve skriptet viste seg å være ganske enkelt:
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);
}
}
}
Prinsippet for dens drift:
- Vi åpner katalogen der vi har samlet pacs.xml-konfigurasjoner fra klienter og plasserer listen over filer i en rekke skalarer (@report_files);
- I en loop behandler vi én fil om gangen og leser den linje for linje;
- Ved å bruke split deler vi hver linje i 5 deler, ved å bruke anførselstegn som skilletegn;
- Vi finner en linje med ordet lytter og plasserer data unike for hver fil (AE-klientnavn og TCP-portnummer) i to variabler;
- Etter dette genererer vi ganske enkelt en ny XML-fil, legger inn unike parametere i den og setter deretter inn det nødvendige antallet PACS-servere med parameterne deres - de. hva det hele startet for)
- Vi skriver om den nye XML-filen på toppen av den gamle.
Det skal bemerkes at jeg faktisk ikke bruker dette skriptet helt automatisk - faktisk kopierer jeg de innsamlede konfigurasjonene til en egen katalog og kjører deretter skriptet og endrer dem alle massevis. Deretter en tilfeldig sjekk - og konfigurasjonene kan distribueres tilbake til maskinene.
Distribuere modifiserte pacs.xml-filer til klienter
Det enkleste som kom til tankene var å gjøre endringer i den allerede fungerende .bat-filen som samler inn konfigurasjoner fra klienter og legge til linjen:
If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml
Den endelige .bat-filen ser slik ut:
@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
Konklusjon
Det er slik"kne" løsning. Vi har allerede prøvd det to ganger (i september 2018 og februar 2019), så langt er flyturen normal. Selvfølgelig oppdaterer ikke 100 % av klientene, men det er nær denne verdien - vi fullfører resten eksternt. Manus av
Kilde: www.habr.com