Plugin Architecture: come gestire database e logging?

2

Sono in procinto di progettare un'architettura per un'applicazione basata su plugin e ho alcune domande su come gestire l'accesso al database e la registrazione. L'obiettivo della mia applicazione è quello di consentire a un dispositivo che la mia azienda produce di inviare messaggi su qualsiasi numero di protocolli di terze parti e su qualsiasi numero di dispositivi di terze parti. A causa della natura della mia applicazione, ho bisogno di registrare ogni messaggio che viene inviato tramite il mio sistema in modo ragionevole.

Ecco cosa sto pensando sul lato Database: ci sarà una tabella di messaggi globale che memorizza tutti i dati agnostici di implementazione che abbiamo, e quindi ci sarà una tabella (o una serie di tabelle) per ogni plugin di messaggistica come definito dal writer del plugin che fa riferimento alla tabella dei messaggi globali tramite una chiave esterna.

Gestisce questi altri tavoli che ho difficoltà a capire come progettare in modo sicuro. Da un lato, non voglio particolarmente dare ai plugin pieno accesso al database (voglio che abbiano il minor numero possibile di privilegi), dall'altro voglio che gli sviluppatori di plugin abbiano pieno dominio per registrare qualsiasi dato bisogno di tabelle che definiscono in modo simile a come funzionano i plugin in Wordpress. Inoltre, non voglio che la registrazione al database sia facoltativa: una buona registrazione è fondamentale per la mia applicazione.

Cose che ho considerato:

  • Progettazione di un'infrastruttura di logging che consente a un plugin di definire (magari in un file XML) le tabelle di cui ha bisogno nel DB e una mappatura tra quelle tabelle e oggetti che restituiranno e utilizzando tali mapping e definizioni di tabella per scrivere su il DB i risultati delle chiamate di metodo.
  • Stabilire una convenzione di denominazione per le stored procedure nel DB che ciascun plugin deve definire quando definisce le proprie tabelle e chiama automaticamente le stored procedure dopo aver inviato un messaggio.
  • Consentendo a ciascun plug-in di implementare un metodo di registrazione che restituisce una stringa contenente la query SQL appropriata.

Ciascuna delle soluzioni di cui sopra mi rende un po 'a disagio, ma non sono sicuro di quali altri approcci potrebbero esistere. Qualche suggerimento?

Dettagli di implementazione: Sto scrivendo la mia domanda in Java e sto usando una soluzione plug-in fatta a mano, quindi ho una discreta quantità di flessibilità. Poiché non è stato scritto nessuno del codice reale (a parte qualche codice di dimostrazione del concetto che è solo per riferimento), posso apportare modifiche al mio piano abbastanza grandi senza costi elevati.

    
posta Brendon Dugan 05.03.2013 - 15:48
fonte

4 risposte

1

Perché deve essere un database? Perché non avere un "dissipatore di dati" generico e scrivere flussi di dati su di esso. I plugin sono responsabili della serializzazione e deserializzazione dei propri dati e forniscono una semplice funzione di lettura / scrittura. Ti forniscono un riferimento a un flusso di messaggi, quindi lo scrivi e restituisci un GUID (o qualche altro token) per identificare i dati.

    
risposta data 05.03.2013 - 17:16
fonte
0

Come pensi di implementare l'invio dei messaggi? Esistono diversi approcci basati su questa risposta. Ad esempio, stai accelerando la tua implementazione personalizzata di Apache James Server? Non hai menzionato se stai lavorando su qualsiasi framework disponibile. Ma penso che un altro approccio che puoi considerare sia quello di utilizzare AOP per questo. Puoi tessere i tuoi aspetti attorno a ciascuna funzione del mittente e ogni volta che tale funzione viene chiamata affermazioni di registrazione può essere preparata e documentata in un db.

    
risposta data 05.03.2013 - 16:22
fonte
0

Qual è lo scopo dei messaggi? Sembra che possano essere senza schema / non strutturati. L'hard-coding dell'implementazione nel database dell'applicazione probabilmente tornerà a perseguitarti. Se la registrazione non è strutturata in ogni caso, perché non fare semplicemente come / use log4j o simili? Un'opzione è semplicemente scrivere un'API wrapper sottile attorno a log4j. Presumibilmente, si desidera mantenere il contesto di registrazione in modo da poter recuperare tutti i registri da tutti i plugin relativi a una singola azione / utente. Se è così, allora hai bisogno di un modo per legare insieme i vari registri.

AppLogger.logMessage (contesto AppContext, plugin PluginContext, log stringa)

il tuo spazio di archiviazione è astratto dai plug-in, che non dovrebbero preoccuparsi di dove vengono registrati i dati. Ciò ti consente di spostarlo facilmente su FS, Code, DB separato, ecc. Senza che i plugin ne siano consapevoli / responsabili.

Se si desidera continuare ad accedere al DB principale, è sufficiente memorizzare i registri nella tabella principale con il messaggio di registro memorizzato come stringa / blob / xml / json, indipendentemente dal supporto del DB.

    
risposta data 05.03.2013 - 17:07
fonte
0

Quello che stai descrivendo è una situazione in cui stai progettando API - tra la tua applicazione e i plug-in. A questo livello dovresti concentrarti sulla progettazione delle interfacce e dei dati che devono essere scambiati senza preoccuparti di alcuna strategia di persistenza specifica. Una volta apposta quella parte, una parte dell'implementazione nella tua applicazione può gestire i dati in qualsiasi modo.

Dato che stai usando Java, dai un'occhiata a qualsiasi API di alto livello che usi già per i suggerimenti di progettazione, come Spring Data, Collezioni (es. Mappa, Elenco), ecc. Nascondono tutti i dettagli dietro Interfacce, Classi astratte e Classi concrete che implementano la funzionalità desiderata.

A un livello molto alto, posso pensare a quanto segue (approccio molto semplicistico, non conoscendo i dettagli esatti):

  1. Un'interfaccia che consente a un plug-in di registrarsi al tuo applicazione. Supponiamo che tu lo chiami PluginRegistry. Quindi il metodo in esso dovrebbe essere rilevante per qualsiasi plugin per registrarsi al applicazione e stabilire i collegamenti di comunicazione (come il messaggio ascoltatori, richiami ecc.). La tua interfaccia può dettare quale / i metodo / i il plugin deve implementare.
  2. Supponiamo che un'altra interfaccia definisca lo scambio di messaggi. Potrebbe essere un'interfaccia di alto livello accoppiata con una classe Abstract (per l'implementazione predefinita) e una o più classi Concrete per implementazioni specifiche. Puoi lasciare l'implementazione delle classi concrete ai plugin.

Le tue classi astratte possono nascondere i dettagli della registrazione nel database. Dato che hai la flessibilità di progettare come dovrebbe apparire il messaggio (il plug-in erediterà e / o implementerà l'interfaccia necessaria), la classe astratta con l'implementazione predefinita può scrivere i dati necessari nel database (preferirei un log file) senza che il plugin ne sappia troppo. In questo modo non è necessario esporre questa funzionalità ai plug-in e in seguito è possibile modificare le implementazioni in base alle esigenze.

Il motivo per cui ho detto che un file di registro è preferito su un relazionale-db è che avrai la flessibilità di loggare come vuoi in un file. Un db NoSQL sarebbe anche una buona scelta qui in quanto non ti costringerà a relazioni difficili tra i tuoi dati nelle prime fasi. Quindi scrivi alcuni script (ad es. In Python, Perl ecc.) Per analizzare i file di log e raccogliere i dati necessari e inserire il relazionale-db come necessario per i report. Ma il tuo archivio dati principale principale sarà costituito da file di registro. Man mano che la tua applicazione matura, avrai una buona idea della struttura dei dati, degli elementi importanti e automatizzerà gli script di analisi. Quando registri più tipi di dati, dovrai aggiornare gli script in base alle esigenze, ma non cambierai le tabelle db dove e interrompendo la tua applicazione.

    
risposta data 05.05.2013 - 18:32
fonte

Leggi altre domande sui tag