2015-09-03 33 views
5

Come menzionato in Apache Camel, consente di scrivere URI dinamico in To(), consente di scrivere URI dinamico in Da(). Causa Ho bisogno di chiamare più postazioni FTP per scaricare i file sulla base della configurazione che sto per memorizzare nel database.Come utilizzare un URI dinamico in From()

(FTPHost, FTPUser, FTPPassword, FTPSourceDir, FTPDestDir) 

Leggere questa configurazione dal DB e passarla dinamicamente al percorso Camel in fase di esecuzione.

Esempio: Questo è l'esempio percorso cammello che devo scrivere in modo dinamico

<Route> 
    <from uri="ftp://${ftpUser}@${ftpHost}:${ftpPort}/${FTPSourceDir}?password=${ftpPassword}&delete=true"/> 
    <to uri="${ftpDestinationDir}"/> 
</Route> 

Come si vede nell'esempio, ho bisogno di passare questi parametri menzionati in modo dinamico. Così come utilizzare uri dinamica Da()

risposta

5

Lo si può leggere dal file di proprietà come segue,

<bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer"> 
    <property name="location" value="classpath:/config/Test.properties"/> 
    </bean> 

<Route> 
    <from uri="ftp://{{ftpUser})@${{ftpHost}}:{{ftpPort}}/${{FTPSourceDir}}?password={{ftpPassword}}&delete=true"/> 
    <to uri="{{ftpDestinationDir}}"/> 
</Route> 

ftpuser, ftpHost .... - tutti sono chiavi dichiarati nel Test.properties

Se si desidera ottenere dinamicamente tali variabili dal proprio scambio, non è possibile farlo in modo regolare come indicato nel proprio esempio. Devi utilizzare il modello di consumo come segue,

Exchange exchange = consumerTemplate.receive("ftp:"+url); 
producerTemplate.send("direct:uploadFileFTP",exchange); 

Devi farlo da un produttore di fagioli o cammelli. Il modello consumer verrà utilizzato dal componente specificato e tale modello produttore invocherà il componente diretto dichiarato nel tuo contesto camel.xml

Nota: i modelli Consumer e Producer sono leggermente costosi. è possibile iniettare entrambi nel contenitore della molla e lasciare che la molla gestisca il ciclo di vita.

+0

Diciamo che ho server ftp 3, come posso passare ogni server uno dopo l'altro ad una via? – hipokito

0

Penso che sia possibile implementare le proprie esigenze all'interno di un percorso Camel.

Poiché si desidera eseguire il polling di più siti FTP, è necessario in qualche modo attivare questo processo. Forse potresti farlo basandoti su un timer Quartz2. Una volta attivato, è possibile leggere i siti FTP configurati from your database.

Per eseguire il polling dei siti FTP specificati è possibile utilizzare Content Enricher pattern per eseguire il polling (vedere: pollEnrich) un URI valutato dinamicamente.

Il percorso di base finale può essere simile a questo (pseudocodice):

from("quarz...") 
to("sql...") 
pollEnrich("ftp...") 
... 
1

ho aiutare una squadra che gestisce un broker di messaggi di commutazione circa un milione di messaggi al giorno. Ci sono oltre 50 destinazioni dalle quali dobbiamo interrogare i file su tutti i marchi di condivisione file (FTP, SFTP, NFS/file: ...). Mantenere fino a 50 distribuzioni che ascoltano ciascuna una directory locale/remota è in effetti un sovraccarico rispetto a un singolo connettore FILE in grado di eseguire il polling dei file in 50 posti in base alla pianificazione specifica e alle impostazioni di sicurezza di ciascuno ... Stessa storia per ottenere e-mail da caselle pop3 e IMAP.

Nel Camel, la sagoma di una soluzione è la seguente:

  • non hai scelta, ma di utilizzare il java DSL configurare almeno il da() parte di tuoi percorsi con un URI che è possibile infatti leggere/costruire da un database o ottenere da una richiesta di amministratore per avviare una nuova rotta. XML DSL consente solo injecting properties risolti una volta quando viene creato il contesto Camel e mai più in seguito.
  • l'idea di base è quella di iniziare percorsi, lasciarli correre (ascoltare o poll una risorsa precisione), e poi l'arresto & ricostruirli su richiesta utilizzando i Camel contesto API per gestire lo stato di RouteDefinitions, Percorsi e possibilmente Endpoint
  • personalmente, mi piace implementare tale istanza dinamica da() su rotte minimaliste con solo la parte 'di' della route, ovvero from(uri).to("direct:inboundQueue").routeId("myRoute"), e quindi definire - in java o XML - un chunk di percorso comune che gestisce il resto del processo: from("direct:inboundQueue").process(..).etc... .to(outUri)
  • consiglierò fortemente combinare Camel con il quadro primavera, in particolare Spring MVC (o Primavera integrazione HttpGateway) in modo che si gode la capacità di costruire rapidamente REST, SOAP, HTTP/JSP, o interfacce di fagioli JMX per amministrare creazione del percorso, la distruzione e aggiornamenti all'interno di un contenitore Spring + Camel, entrambi nicely integrated.
  • È quindi possibile dichiarare nel contesto dell'applicazione Spring un bean che si estende SpringRouteBuilder, come al solito quando si costruiscono percorsi Camel con lo java DSL in Spring; nell'implementazione @Override configure() metodo obbligatorio, si deve salvare il routeDefinition oggetto costruita con il metodo from(uri), e assegnarle un noto Stringroute-id con il metodo .routeId(route-id); Ad esempio, è possibile utilizzare l'id di percorso come chiave in una mappa degli oggetti di definizione percorso già creati e avviati, nonché una chiave nel proprio DB di URI.
  • poi si estende il SpringRouteBuilder di fagioli che hai dichiarato con nuovi metodi createRoute (route-id), updateRoute (route-id), e removeRoute (route-id); I parametri route-id associati necessari per la creazione o l'aggiornamento verranno recuperati dal database o da un altro registro e il metodo pertinente, in esecuzione nel bean RouteBuilder, trarrà vantaggio dalla funzione getContext() per recuperare l'attuale ModelCamelContext, che a sua volta viene utilizzato a stopRoute(route-id), removeRoute(route-id), e quindi addRouteDefinition(qui è dove è necessario l'oggetto routeDefinition), e, infine, startRoute(route-id) (Nota: attenzione ai possibili endpoint fantasma, che non sarebbe stato rimosso, come spiegato nella removeRoute() javadoc)
  • tua interfaccia di amministrazione (che di solito assume la forma di un componente/bean Spring @Controller che gestisce il traffico HTTP/REST/SOAP) avrà davvero un lavoro facile da ottenere l'estensione SpringRouteBuilder creata in precedenza da Bean iniettata da Spring nel bean controller e quindi accede a tutti i necessari metodi createRoute(route-id), updateRoute(route-id) e removeRoute(route-id) aggiunti all'estensione SpringRouteBuilder Bean.

E funziona bene. L'implementazione esatta con tutto il codice di gestione degli errori e di convalida che si applica è un po 'troppa del codice da pubblicare qui, ma hai tutti i collegamenti a "how to's" pertinenti in precedenza.

4

da Camel 2.16 on-reparti, possiamo usare componente pollenrich per definire il polling dei consumatori come il file, ftp..etc con URL dinamico/valore del parametro come qui di seguito

<route> 
    <from uri="direct:start"/> 
    <pollEnrich> 
    <simple>file:inbox?fileName=${body.fileName}</simple> 
    </pollEnrich> 
    <to uri="direct:result"/> 
</route> 

sua awesomeeee !!!

consultare: http://camel.apache.org/content-enricher.html

0
Use Camel endpoint with spring spel expression. 

Set up a Camel endpoint in the context so it can be accessed from any bean: 

     <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> 
      <endpoint id="inventoryQueue" uri="#{config.jms.inventoryQueueFromUri}"/> 
     </camelContext> 

Now you can reference the inventoryQueue endpoint within the `@Consume` annotation as follows: 
     @org.apache.camel.Consume(ref = "inventoryQueue") 
     public void updateInventory(Inventory inventory) { 
      // update 
     } 

    Or: 
    <route> 
     <from ref="inventoryQueue"/> 
     <to uri="jms:incomingOrders"/> 
    </route>