Personal tools
La nobile arte della migrazione: Transmogrifier

Transmogrifier

May 04, 2012

La nobile arte della migrazione: Transmogrifier

Storia di una migrazione da Plone 3.2.3 a Plone 4.1.2

Nella vita di un informatico, quale che sia la piattaforma su cui lavora, come Plone o un qualsiasi altro sistema, prima o poi arriva il momento in cui il cliente dice:

“Ho visto che è uscita la nuova versione del software, noi non migriamo?”

La risposta è alquanto ovvia, ma la realizzazione di quanto promesso può nascondere qualche insidia.

La piattaforma su cui lavoriamo, Plone, è arrivata alla versione 4.1.4 e di versioni differenti ne sforna parecchie. Noi non siamo affatto digiuni di migrazioni, però. Abbiamo fatto un salto dalla versione 2.5.4 alla 3.1.7, da una 3.2.3 siamo passati ad una 3.3.5.

Non ci facciamo certo spaventare da una migrazione e quindi: migriamo!

Plone è un buon prodotto e quindi il suo bel tool di migrazione ce l’ha compreso. La nostra esperienza però ci dice che il tool automatico a volte può risultare pericoloso, soprattutto se le versioni intermedie sono molte, se il sistema è complesso e si hanno un buon numero di add-on.

Scendiamo nel caso, per analizzare meglio il processo di migrazione: il portale della Rete Civica di Modena. Il progetto è abbastanza complesso e prevede:

  • circa 30mila elementi in catalogo;
  • una cinquantina tra prodotti e temi aggiuntivi (il portale è dotato di sottositi);
  • una decina di tipi custom;
  • un buon numero di portlet aggiuntive.

Quindi, forse la migrazione automatica non è la strada migliore; quali altre possibilità abbiamo?

Tra le varie alternative valutate scegliamo transmogrifier, uno strumento che abbiamo già scelto altre volte e di cui non ci siamo pentiti. Per essere precisi scegliamo quintagroup.transmogrifier, che sembra proprio fare al caso nostro, dato che nel wiki c’è addirittura una sezione chiamata Content migration from Plone 3 to Plone 4 (Plone 3.2 -> Plone 4.0).

La spiegazione dei passi da eseguire è molto semplice. Facciamo i test tra due buildout base Plone 3.2 e Plone 4 e un test con un clone del sistema che andremo a migrare e ci riteniamo abbastanza soddisfatti; dico abbastanza perchè alcune cose che non vanno o che etichettiamo come "da fare a mano" le troviamo, ma sembrano cose minori.

E invece il sistema di produzione, con tutti i suoi dati e tutti i suoi casi particolari presenta sempre insidie nascoste.

I Problemi

Sicuramente al primo posto metto il fatto che non siamo riusciti a fare un export (e relativo import) di tutti i contenuti del portale in una volta sola a causa di un out of memory del sistema.

La macchina su cui abbiamo fatto la migrazione era anche abbastanza carrozzata, ma la mole di dati che Plone doveva tenere in memoria da esportare, per poi creare un unico .tar.gz, produceva questo tipo di errore.

La soluzione più adatta ci è sembrata quella di spezzare l'operazione in sei parti.

...

[sitewalker_parte4]
blueprint = quintagroup.transmogrifier.sitewalker
condition = python:context.getPortalTypeName() not in ('Plone Site') 
              and [x for x in ['/monet/xxx','/monet/yyy','/monet/zzz','/monet/xyz','/monet/zyx'] 
              if '/'.join(context.getPhysicalPath()).startswith(x)] != []

[sitewalker_parte5]
blueprint = quintagroup.transmogrifier.sitewalker
condition = python:context.getPortalTypeName() not in ('Plone Site') 
              and [x for x in ['/monet/xxx','/monet/yyy','/monet/zzz','/monet/zyz'] 
              if '/'.join(context.getPhysicalPath()).startswith(x)] != []

...


Abbiamo anche dovuto intervenire direttamente nel codice sia di quintagroup.trasmogrifier che di Plone a causa di una serie problematiche, migliorie e bug minori che però impedivano alla procedura di migrazione di andare a buon fine:

  • skip dell'azione di parsing xml durante l'esportazione dei campi di tipo Reference Field, che in alcuni casi non funzionava a dovere;
  • aggiunti alcuni controlli durante l'estrazione delle proprietà dagli oggetti per non far rompere la procedura e skippare la proprietà con un'eccezione;
  • alcune portlet presentavano campi senza un valore significativo per cui è stato necessario inserire un default coerente con il tipo di campo;
  • controllo e skip degli elementi che generano errori alla creazione così da non bloccare la procedura;
  • aggiunto il commit della transazione dopo la creazione di ogni oggetto in modo da non dover effettuare un'unica grande transazione;
  • creato un ripristino per la data di modifica degli oggetti che veniva sostituita con la data in cui viene fatta l'importazione dall'evento ObjectInitializedEvent;
  • inserito un setter fake per il campo Description nei criteri delle collezioni dato che la procedura considera tale campo sempre presente (elementi come i criteri delle collezioni non hanno la descrizione e quindi la procedura setta per acquisizione la descrizione della collezione stessa);
  • fix per il salvataggio del nome del file nei blob.
  • aggiunta la gestione dell'importazione dei campi Reference Field; la procedura originale ne permetteva solo uno in ogni AT.

Come procedure aggiuntive alla migrazione tramite transmogrifier abbiamo dovuto creare:

  • un export/import in csv del tool di redirezione (Redirection Tool) di Plone;
  • un export/import degli utenti e dei gruppi basata su un blueprint di transmogrifier;
  • un export/import per alcune interfacce necessarie per il funzionamento di alcuni nostri prodotti installati (redturtle.subsite, monet.calendar.star, monet.mapsviewlet);
  • procedura in importazione via Python script di alcuni correlati. Questo si è reso necessario dato che i correlati non vengono salvati se l'oggetto referenziato non è già presente nel portale (in fase di importazione via transmogrifier i correlati non presenti sono stati salvati nelle annotazioni dell'oggetto in modo da poterli leggere in un secondo momento dallo script).

L’esperienza insegna!

In quintagroup.transmogrifier si hanno già preconfigurate le pipeline di export e di import, che sono state create e cablate intorno al Marshall (Products.Marshall), e ad altre funzionalità di import/export di Plone rendendo l’integrazione con altri blueprint difficoltosa.

Tali dinamiche sono ovviamente modificabili ma il core deve rimanere e quindi non si ha una grande possibilità di manovra in questo senso.

Un'alternativa potrebbe essere l'utilizzo di collective.transmogrifierplone.app.transmogrifier, che danno la possibilità di costruirsi la propria pipeline usando tutti i blueprint che si ritengono utili.

Si riesce a gestire molto bene il tipo di input, si può modificare, spostare, accorpare i dati che si sta trasferendo, e si possono anche utilizzare blueprint custom auto-prodotti.

La difficoltà in questo caso è data dalla necessità di costruirsi tutti i meccanismi per l'esportazione e l'importazione dei contenuti e dei vari altri elementi Plone; mentre per fare delle piccole importazioni è sicuramente consigliabile.

Filed under: , ,
comments powered by Disqus