2010-01-24 9 views
5

Spesso collaudo la mia applicazione con una copia di un database attivo, ma devo fare attenzione a non eseguire alcuna azione che causa l'invio di un'email a un utente. Mi piacerebbe avere un modo per configurare la primavera in modo tale che quando sono in modalità di sviluppo o test, che nessuna email verrà inviata agli utenti reali. Idealmente, mi piacerebbe che tutte le e-mail che avrebbero dovuto andare all'utente venissero invece a una casella di posta che posso esaminare. E non voglio cambiare alcun codice per farlo accadere, solo i file di configurazione xml.Modifica impostazioni e-mail Spring in base alla modalità dev/test/prod

Sto già utilizzando PropertyPlaceholderConfigurer e sto leggendo in diversi file di proprietà in base a se sono in esecuzione in modalità produzione, test o dev. Configuro un JavaMailSenderImpl in base ai valori nel file delle proprietà. Sto anche usando un SimpleMailMessage per creare un modello con l'indirizzo Da.

Idealmente ci sarebbe un modo per riscrivere l'indirizzo TO di tutte le e-mail in uscita a un account di prova se sto correndo in modalità dev o test.

Il mio primo pensiero è stato quello di utilizzare un server SMTP diverso per dev e test. Ma poi dovrei anche gestire un altro server di posta, e dovrei personalizzarlo in modo che non invii posta a nessun'altra parte, ma lo invii invece a una singola casella di posta. Non voglio aggiungere ulteriori requisiti di gestione, se possibile.

Forse questa è la soluzione migliore, ma sembra che ci dovrebbe essere un modo per intercettare le e-mail e cambiare il destinatario.

Qualcuno ha già avuto a che fare con questo problema? Che soluzioni hai trovato?

+0

come stai eseguendo i tuoi test? – Bozho

+0

bozho - al momento, non ho alcun test unitario che coinvolga la posta elettronica. il sistema invia solo email quando viene creato un nuovo account. ma ora ho bisogno di espanderlo per inviare notifiche su molte azioni diverse. e non voglio che i membri ricevano queste e-mail quando i tester utilizzano il server di test o gli sviluppatori sono in esecuzione localmente. – Tauren

+0

Controlla la mia risposta http: // stackoverflow.it/questions/8599791/a-simple-local-smtp-server/22043597 # 22043597 –

risposta

1

Vedo che si specifica un requisito specifico che non si desidera modificare alcun codice. Vorrei ancora suggerire di creare un'implementazione stub di JavaMailSender. In questo modo, è possibile iniettare l'oggetto stub nel proprio sviluppo e nelle build di test.

+0

Buhb: in realtà, non mi interessa creare uno stub, come dici tu. In effetti, se è dimostrato che è la soluzione migliore, potrei cambiare altro codice a questo punto. Preferirei semplicemente non cambiare le cose nel mio livello di servizio. Quindi non avrei dovuto farlo sembrare un requisito così severo. – Tauren

1

Dai un'occhiata a mock-javamail (fa quello che la risposta precedente suggerisce) o una soluzione forse ancora più rapida è un server SMTP falso come Fakemail.

+0

akhnaten - grazie, non ero a conoscenza di nessuno di questi strumenti, e potrebbero certamente aiutare. Tuttavia, preferirei avere un modo per mandare ancora e-mail davvero, ma ho semplicemente l'indirizzo TO riscritto su un indirizzo che ho specificato. Non sembra che questi strumenti lo facciano. – Tauren

+0

Con un server SMTP falso tutte le e-mail vengono inviate via SMTP come al solito, tranne che il server SMTP in realtà non le consegna ma le salva su file locali dove è possibile ispezionarle. Quindi non c'è bisogno di cambiare il destinatario. –

2

Ho avuto un requisito simile in passato e la mia soluzione era scrivere quello che ho chiamato EnvironmentSelectingFactoryBean (Spring sembra incoraggiare nomi di classi lunghi ...). Si trattava di un'implementazione FactoryBean che "selezionava" uno di un intervallo di bean disponibili in base all'ambiente di applicazione corrente.

Se vi mostro qualche esempio di XML, penso che si otterrà l'idea:

<bean id="mailSender" class="com.kizoom.spring.config.EnvironmentSelectingFactoryBean"> 
    <property name="beanMap"> 
     <map> 
     <entry key="test"> 
      <bean class="org.springframework.mail.javamail.JavaMailSenderImpl"> 
       <property name="host" value="${mailhost.test}"/> 
      </bean> 
     </entry> 
     <entry key="production"> 
      <bean class="org.springframework.mail.javamail.JavaMailSenderImpl"> 
       <property name="host" value="${mailhost.production}"/> 
      </bean> 
     </entry> 
     </map> 
    </property> 
</bean> 

Quindi, EnvironmentSelectingFactoryBean sa se si sta eseguendo in modalità "produzione" "test" o, raccoglie l'appropriato bean dal beanMap e sputa il nostro dal suo metodo FactoryBean.getObject(). Entrambi i bean nello beanMap sono veri mittenti di posta, non stub, ciascuno con valori di segnaposto diversi, ma non si corre il rischio di ottenere quello sbagliato.

Il codice cliente vedrà solo un singolo bean JavaMailSender.

4

Nota: la mia risposta si basa sull'utilizzo di Maven, quindi questo è più sulla costruzione che su qualsiasi cosa, ma l'uso della molla mi consente di iniettare i valori in modo conveniente.

Io uso un property-placeholder e costruire fagioli come:

JDBC.proprietà:

db.url=hostname:1521/test 
db.username=awesome 
db.password=password 

applicationContext.xml (utilizzando namespace contesto)

<context:property-placeholder location="classpath:jdbc.properties"/> 
<bean id="yo" class="some.DataSource"> 
    <property name="url" value="${db.url}"/> 
    <property name="username" value="${db.username}"/> 
    <property name="password" value="${db.password}"/> 
</bean> 

Poi memorizzare gli ambienti in cartelle separate con valori specifici domini come:

src/main/environments 
++ prod 
+++++ jdbc.properties 
++ dev 
+++++ jdbc.properties 
++ cert 
+++++ jdbc.properties 

profili Maven Uso (da pom.xml):

<profile> 
    <id>environment</id> 
    <activation> 
     <property> 
      <name>environment</name> 
     </property> 
    </activation> 
    <build> 
     <resources> 
      <resource> 
       <directory>src/main/environments/${environment}</directory> 
      </resource> 
     </resources> 

È possibile eseguire qualsiasi comando Maven con la proprietà -Denviroment di flettere le proprietà:

mvn clean -Denvironment=dev test 
mvn clean -Denvironment=cert package 
mvn clean -Denvironment=prod deploy 

ecc e tutti i file da quella cartella ambiente vengono copiati nella destinazione o artefatto insieme a tutti i principali file src// risorse.

1

Un'altra opzione con titolare del posto proprietà è caricare dinamicamente un file di proprietà in base alla proprietà di sistema in fase di esecuzione.

/WEB-INF/config/myapp.${myapp.env}.properties

WEB-INF/conf avrà myapp.prod.properties myapp.stag.properties myapp .test.properties

Aggiungi -Dmyapp.env = pungolo al tomcat o lo script di avvio dei server delle applicazioni.

0

La soluzione migliore è creare javax.mail.Session come risorsa JNDI. Quindi è possibile impostare diversamente per prod/test e dev. E non ti devi preoccupare di modificare le impostazioni nella tua app perché l'unica differenza è gestita dal server.

Per dev * e ** test Posso consigliarti una buona simulazione di javax.mail.Session.

Un progetto github javaMail extension aggiunge trasporto di file che permette di:

  • Salva mail ai file in formato text invece di inviare loro
  • Salva mail ai file in formato mbox invece di inviarli
  • aggiungi informazioni di registro invece di inviare e-mail