Ich habe eine RouteBuilder
Unterklasse, die meine Camel-Routen einrichtet. Es ist von Frühling gebaut. Zunächst sah es so etwas wie diese:Camel: Wie man eine Route bedingt von der Konfiguration baut?
@Override
public void configure() throws Exception {
from(...)
.process(...)
.to(...)
}
Was Ich mag würde, ist ein zusätzliches Endpunkt-Routing auf Konfiguration basierte tun hinzuzufügen. Es gibt eine Eigenschaftendatei, die Spring verwendet, um die RouteBuilder
Bean zu erstellen, und eines der Felder, die es festlegt, ist boolean addAnotherEndpoint
. Wenn dieser Boolesche Wert wahr ist, möchte ich einen weiteren to
hinzufügen. Wenn es falsch ist, möchte ich, dass es auf sein aktuelles Verhalten zurückfällt. So habe ich es dies:
@Override
public void configure() throws Exception {
from(...)
.process(...)
.to(...)
.choice()
when(constant(addAnotherEndpoint)).to(...)
.endChoice();
}
Während dies scheint das gewünschte Verhalten habe ich Probleme habe für sie zu schreiben Unit-Tests (weil es den Wert von addAnotherEndpoint
aus den Eigenschaften ziehen Datei obwohl ich versuche, um es in meinen Tests zu überschreiben). Gibt es einen besseren Weg, damit umzugehen? Wird meine derzeitige Methode unbeabsichtigte Nebenwirkungen haben?
EDIT:
-I-Tests bin mit einer CamelSpringTestSupport
Unterklasse (mit JUnit-Tests). In der @Before
Methode erstelle ich eine AdviceWithRouteBuilder
, die alle Endpunkte durch Mocks ersetzt. In meinem @Test
, bin ich versucht, den Wert von addAnotherEndpoint
außer Kraft zu setzen, die von der Properties-Datei genommen wird:
@Test
public void testConditionalRouting() throws Exception {
context.start();
MyRouteBuilder routeBuilder = (MyRouteBuilder) applicationContext.getBean("myRouteBuilder");
routeBuilder.setAddAnotherEndpoint(true);
getMockEndpoint("myMockEndpoint").expectedMessageCount(1);
sendMockMessage();
assertMockEndpointsSatisfied();
context.stop();
}
Es gibt einen entsprechenden Test, der addAnotherEndpoint
-false
setzt und behauptet, dass 0-Nachrichten empfangen wurden. Das Problem besteht darin, dass das Überschreiben des Werts dieser Variablen nicht funktioniert. Ein Test wird bestanden und der andere schlägt fehl, je nachdem, ob in der Eigenschaftendatei der Wert true
oder false
lautet. Was dies für mich nahe legt, ist, dass die Route erstellt wird, bevor ich die Einstellung überschreibe (und damit auch bevor der Kontext gestartet wird). Ich habe einen Debugger eingecheckt und die Einstellung ist korrekt überschrieben. Es scheint nur keinen Einfluss zu haben.
EDIT 2:
Aus meiner AdviceWithRouteBuilder
:
@Override
public void configure() throws Exception {
replaceFromWith(MOCK_FROM_ENDPOINT);
interceptSendToEndpoint(FIRST_TO_ENDPOINT)
.skipSendToOriginalEndpoint().to(MOCK_FIRST_TO_ENDPOINT);
weaveById(MY_PROCESSOR_ENDPOINT).replace()
.to(MOCK_MY_PROCESSOR_ENDPOINT);
weaveById(SECOND_TO_ENDPOINT).replace()
.to(MOCK_SECOND_TO_ENDPOINT);
}
Dies ersetzt jedes EIP mit einem Mock-Endpunkt. Ich habe 4 Tests, die sich auf diese verlassen, und sie scheinen zu funktionieren, wie erwartet, das einzige Problem ist das bedingte Routing.
Abgesehen von JUnit-Annotationen sind die einzigen Annotationen in meiner Testklasse @Override
auf isUseAdviceWith()
(gibt True zurück) und createApplicationContext()
, die einen neuen Spring Application Context zurückgibt.
Ich habe meine Tests ohne context.start()
ausgeführt und der einzige, der bestanden hat, war derjenige, der behauptet, dass 0 Nachrichten empfangen wurden (was sinnvoll ist, wenn die Route nicht gestartet wurde). Ich glaube also nicht, dass der Kontext automatisch gestartet wird.
Das sieht für mich sehr normal aus. Ich denke, das einzige Problem wäre die Art, wie Sie es testen. In einer Live-Umgebung sollte diese Route in Ordnung sein. Können Sie mitteilen, wie Sie es testen? Dann können wir das auch beheben. Übrigens wäre es einfacher, wenn Sie einen Filter anstelle von Choice verwenden, der nur eine Bedingung hat. –
Danke für den Vorschlag. Ich verwende eine CamelSpringTestSupport-Unterklasse, um sie zu testen. Ich werde die Frage aktualisieren, um dies zu berücksichtigen. – tytk
Kann ich auch Ihren AdviceWithRouteBuilder-Block sehen? Hat Ihre Testklasse auch Anmerkungen? Kannst du context.start() auch entfernen? vom Anfang Ihrer Tests, und führen Sie sie aus, um zu sehen, ob der Kontext überhaupt automatisch startet? Wenn ja, ist das Problem dort ... –