Pré-história
Uma organização médica implementou soluções baseadas em servidores Orthanc PACS e cliente Radiant DICOM. Durante a configuração, descobrimos que cada cliente DICOM deve ser descrito nos servidores PACS da seguinte forma:
- Nome do cliente
- Nome AE (deve ser exclusivo)
- Uma porta TCP que abre automaticamente no lado do cliente e recebe pesquisas DICOM do servidor PACS (ou seja, o servidor as envia para o cliente - iniciando a conexão primeiro)
- Endereço IP
Após configurar o Radiant, os clientes receberam o seguinte pensamento: para cada cliente, configurar o software com os parâmetros acima resultou no preenchimento do arquivo pacs.xml, que estava localizado no perfil do usuário (caminho: %APPDATA%RadiantViewerpacs.xml). Ao mesmo tempo, a configuração de um cliente diferia de outro em pelo menos dois parâmetros (o nome AE é diferente para todos, e a porta é basicamente a mesma, exceto para clientes terminais rodando no mesmo servidor - lá as portas também tinham a ser atribuído diferente).
Exemplo de arquivo pacs.xml por
Durante cerca de seis meses tudo correu bem, o sistema começou a funcionar... e então chegou até nós”subaquático pedras»:
- Precisamos colocar em operação vários novos servidores PACS que irão substituir os antigos (onde o espaço em disco começou a acabar). Servidores PACS em máquinas virtuais, mas não é disso que estamos falando;
- Precisamos alterar de alguma forma centralmente as configurações exclusivas (com dois parâmetros diferentes) em 200 máquinas (seu número aumentava regularmente);
- Considerando a taxa de crescimento dos volumes de inquéritos, é necessária uma solução não apenas uma vez, mas replicada e regularmente (por exemplo, uma vez a cada 1-3 meses).
Escolhendo ferramentas para resolver um problema
A princípio, houve tentativas de encontrar alguma solução que modificasse o arquivo pacs.xml no lado do cliente e fizesse alterações na lista de servidores PACS sem afetar o nome do AE e as configurações da porta TCP. Os clientes Windows naquela época eram baseados no Windows XP e no Windows 7 - então houve tentativas de escrever algo assim baseado em VBScript. Mas, infelizmente, não foi possível dominar tal tarefa, devido à total falta de experiência em escrever algo complexo e abrangente nesta linguagem. As tentativas de localizar e reescrever também não tiveram sucesso (deve-se notar que eu já tinha um plano diferente em mente, então não mexi no VBScript por mais de 3-4 horas).
No final, decidi pela seguinte solução:
- Usando a política de grupo, reúna todos os arquivos pacs.xml em um local em qualquer servidor em um recurso de rede;
- Alterar arquivos em massa (já tinha experiência em resolver esses problemas usando Perl);
- Use também políticas de grupo para atualizar as configurações do cliente.
Coletando arquivos usando Política de Grupo
A parte mais simples é que quando um cliente faz login em seu perfil, ele, com seus direitos, executa um determinado arquivo .bat, que afirma:
echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml
Assim, os arquivos pacs.xml serão acumulados no servidor em um recurso oculto, cujo nome contém informações de qual computador e de qual usuário esta configuração foi copiada.
O mais difícil foi esperar até que esta política funcionasse para todos os usuários.
Alterando configurações usando um script Perl
Vamos precisar
O script em si acabou sendo bastante simples:
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);
}
}
}
O princípio de seu funcionamento:
- Abrimos o diretório no qual coletamos as configurações pacs.xml dos clientes e colocamos a lista de arquivos em uma matriz de escalares (@report_files);
- Em um loop, processamos um arquivo por vez e o lemos linha por linha;
- Usando split, dividimos cada linha em 5 partes, usando aspas como separador;
- Encontramos uma linha com a palavra listener e colocamos os dados exclusivos para cada arquivo (nome do cliente AE e número da porta TCP) em duas variáveis;
- Depois disso, simplesmente geramos um novo arquivo XML, inserimos parâmetros exclusivos nele e, em seguida, inserimos o número necessário de servidores PACS com seus parâmetros - aqueles. para que tudo começou)
- Reescrevemos o novo arquivo XML sobre o antigo.
Deve-se observar que, na verdade, eu não uso esse script de forma totalmente automática - na verdade, copio as configurações coletadas em um diretório separado e, em seguida, executo o script e altero todas elas em massa. Em seguida, uma verificação aleatória - e as configurações podem ser distribuídas de volta às máquinas.
Distribuindo arquivos pacs.xml modificados para clientes
A coisa mais simples que me veio à mente foi fazer alterações no arquivo .bat já funcional que coleta configurações dos clientes e adicionar a linha:
If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml
O arquivo .bat final fica assim:
@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
Conclusão
É tipo isso "joelho"solução. Já tentamos duas vezes (em setembro de 2018 e fevereiro de 2019), até agora o voo está normal. Claro que não atualiza 100% dos clientes, mas está próximo desse valor - finalizamos o restante remotamente. Roteiro de
Fonte: habr.com