Modifica delle impostazioni del software mantenendo le preferenze personali

Contesto

In un'organizzazione sanitaria sono state implementate soluzioni basate su server PACS Orthanc e sul client DICOM Radiant. Durante la configurazione, si è scoperto che ogni client DICOM doveva essere descritto nei server PACS nel seguente modo:

  • Nome del cliente
  • Nome AE (deve essere unico)
  • Porta TCP, che si apre automaticamente dal lato del client e accetta gli esami DICOM dal server PACS (cioè, il server spinge essenzialmente gli esami verso il client - iniziando per primo la connessione)
  • Indirizzo IP

Dopo la configurazione dei clienti Radiant, è emersa la seguente informazione da considerare: per ogni cliente, la configurazione del software con i parametri sopra indicati portava alla generazione di un file pacs.xml, che si trovava nel profilo utente (percorso: %APPDATA%RadiantViewerpacs.xml). Tuttavia, la configurazione di un cliente differiva da quella di un altro per almeno due parametri (il nome AE era diverso per tutti, mentre la porta è generalmente la stessa, eccetto per i client terminali che lavorano sullo stesso server - anche per quelli era necessario assegnare porte diverse).

Esempio di file pacs.xml per link:

Per circa sei mesi tutto è andato bene, il sistema ha funzionato… e poi siamo stati avvisati di "insidie nascoste»:

  • Dobbiamo implementare alcuni nuovi server PACS per sostituire quelli vecchi (dove lo spazio su disco è quasi esaurito). I server PACS sono in macchine virtuali, ma non è questo il punto;
  • Dobbiamo in qualche modo modificare centralmente le configurazioni uniche (con due parametri differenti) su 200 macchine (il cui numero è aumentato regolarmente);
  • Considerando il ritmo di crescita dei volumi di esami, la soluzione deve essere sostenibile e ripetibile (ad esempio, una volta ogni 3-5 mesi).

La soluzione è riportata di seguito.

Scelta degli strumenti per affrontare il problema

All'inizio ci sono state tentativi di trovare una soluzione che modificasse il file pacs.xml lato client, apportando modifiche all'elenco dei server PACS senza toccare le impostazioni del nome AE e la porta TCP. I client Windows in quel momento erano basati sia su Windows XP che su Windows 7; quindi ci sono stati tentativi di scrivere qualcosa basato su VBScript. Purtroppo, non sono riuscito a portare a termine un compito del genere, a causa della totale mancanza di esperienza nella scrittura di qualcosa di complesso e articolato in questo linguaggio. I tentativi di trovare e riscrivere non hanno avuto successo (è giusto notare che avevo già un altro piano in mente, quindi non ho continuato con VBScript per più di 3-4 ore).

Alla fine ho optato per la seguente soluzione:

  • Raccogliere tramite criteri di gruppo tutti i file pacs.xml in un unico posto su un server condiviso;
  • Modificare i file in blocco (avevo già esperienza nella risoluzione di tali problemi, utilizzando Perl);
  • Aggiornare anche le impostazioni dei client tramite criteri di gruppo.

Raccolta dei file tramite criteri di gruppo

La parte più semplice: all'accesso del client al proprio profilo, esegue con i propri diritti un certo file .bat, in cui è scritto:

echo off
Se esiste %APPDATA%RadiantViewerpacs.xml copia %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml

In questo modo, sul server, nel percorso nascosto, si accumuleranno file pacs.xml, il cui nome contiene informazioni su quale computer e quale utente ha copiato questa configurazione.

La parte più difficile è stata aspettare che questa politica fosse applicata a tutti gli utenti.

Modifica delle configurazioni tramite script Perl

Avremo bisogno di Active Perl per Windows di ActiveState, oltre al modulo XML::Writer, che può essere installato con il comando ppm install XML-Writer.

Lo script stesso è risultato piuttosto semplice:

use XML::Writer;
 
# Apriamo la cartella con i report, elaboriamo l'elenco (rimuoviamo l'eccesso):
	$report_dir = "C:Perl64WORKPACS-xml3";
	opendir(DIR, "$report_dir") or die "Impossibile aprire la cartella con i report!";
	@report_files = readdir DIR;
	shift (@report_files); # rimuoviamo il punto dagli elementi dell'array (.)
	shift (@report_files); # rimuoviamo i due punti dagli elementi dell'array (..)
#	print "@report_files";
	closedir(DIR);
 
# Iniziamo a elaborare i file - uno alla volta. Bisogna leggere il parametro AET e il numero della porta in variabili.
foreach $analiz_file (@report_files) 
{
	$full_path_to_file="C:Perl64WORKPACS-xml3".$analiz_file;
	open (INFO, $full_path_to_file);
 
	while ($line = )
	{
		# Le variabili $aet e $port contengono dati unici per ogni file XML:
		my ($other1, $aet, $other2, $port, $other3) = split "/", $line, 5;
		# Se troviamo la stringa listener - siamo arrivati alla riga desiderata e possiamo formare un nuovo XML:
		if ($other1 =~ 'listener')
			{
				# Formiamo un nuovo XML con i campi e i dati necessari:
				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');
 
				# Posizioniamo l'XML pronto nella variabile:
				my $xml = $writer->end();
				# Prepariamo il file per la riscrittura:
				$rewritexml = $full_path_to_file;
				# Riscriviamo i file XML con i nuovi dati:
				open (NEWXML, "> $rewritexml");
				print NEWXML $xml;
				close (NEWXML);				
			}
	}
 
}

Principio di funzionamento:

  • Apriamo la cartella in cui abbiamo raccolto le configurazioni pacs.xml dei clienti e aggiungiamo l'elenco dei file in un array di scalari (@report_files);
  • Nel ciclo trattiamo un file alla volta e lo leggiamo riga per riga;
  • Con split dividiamo ogni riga in 5 parti, utilizzando le virgolette come delimitatore;
  • Troviamo la riga con la parola listener e memorizziamo in due variabili i dati unici per ogni file (nome del cliente AE e numero della porta TCP);
  • Dopo di che formiamo semplicemente un nuovo file XML, scriviamo in esso i parametri unici e poi inseriamo il numero necessario di server PACS con i loro parametri – cioè, ciò per cui è stato tutto progettato)
  • Riscriviamo il nuovo file XML sopra quello vecchio.

Va notato che in realtà non utilizzo questo script in modo completamente automatico – in sostanza, copio le configurazioni raccolte in un'altra cartella e poi, eseguendo lo script, le modifichi tutte in una volta. Successivamente, faccio una verifica selettiva – e le configurazioni possono essere ridistribuite sulle macchine.

Distribuzione dei file pacs.xml modificati ai clienti

La cosa più semplice che mi è venuta in mente è modificare il file .bat già esistente, che raccoglie le configurazioni dai clienti, e aggiungere la seguente riga:

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

Il file .bat finale si presenta così:

@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

Conclusione

Ecco una soluzione «artigianale». L'abbiamo provata già due volte (settembre 2018 e febbraio 2019), e finora tutto procede senza problemi. Certo, non aggiorna il 100% dei clienti, ma ci siamo vicini — gli altri li completando da remoto. Lo script ha link.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster