Skip to content

Commit

Permalink
Merge pull request citrusframework#31 from christophd/issue/30/add-ca…
Browse files Browse the repository at this point in the history
…mel-route-steps

feat: Add Camel route steps
  • Loading branch information
christophd authored Aug 24, 2019
2 parents 6aa9f5c + 73fc200 commit 7bbc4e5
Show file tree
Hide file tree
Showing 10 changed files with 457 additions and 0 deletions.
7 changes: 7 additions & 0 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<log4j2.version>2.12.0</log4j2.version>
<citrus.version>2.8.0</citrus.version>
<cucumber.version>3.0.2</cucumber.version>
<camel.version>2.21.1</camel.version>
<junit.version>4.12</junit.version>
<kubernetes-client.version>4.3.0</kubernetes-client.version>
<postgresql.version>9.4.1212</postgresql.version>
Expand Down Expand Up @@ -69,6 +70,11 @@
<artifactId>yaks-testing</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.yaks</groupId>
<artifactId>yaks-testing-camel</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>dev.yaks</groupId>
<artifactId>yaks-testing-camel-k</artifactId>
Expand Down Expand Up @@ -151,6 +157,7 @@

<modules>
<module>yaks-testing</module>
<module>yaks-testing-camel</module>
<module>yaks-testing-camel-k</module>
<module>yaks-testing-http</module>
<module>yaks-testing-jdbc</module>
Expand Down
83 changes: 83 additions & 0 deletions java/yaks-testing-camel/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>dev.yaks</groupId>
<artifactId>yaks-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>yaks-testing-camel</artifactId>

<dependencies>

<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
</dependency>

<dependency>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-core</artifactId>
<version>${citrus.version}</version>
</dependency>

<dependency>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-java-dsl</artifactId>
<version>${citrus.version}</version>
</dependency>

<dependency>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-camel</artifactId>
<version>${citrus.version}</version>
</dependency>

<!-- Test scope -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.consol.citrus</groupId>
<artifactId>citrus-cucumber</artifactId>
<version>${citrus.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package dev.yaks.testing.camel;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;

import com.consol.citrus.Citrus;
import com.consol.citrus.annotations.CitrusFramework;
import com.consol.citrus.annotations.CitrusResource;
import com.consol.citrus.camel.endpoint.CamelEndpoint;
import com.consol.citrus.camel.endpoint.CamelEndpointConfiguration;
import com.consol.citrus.dsl.runner.TestRunner;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.util.DelegatingScript;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.ModelCamelContext;
import org.apache.camel.model.ModelHelper;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.RoutesDefinition;
import org.apache.camel.spring.SpringCamelContext;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.core.io.ByteArrayResource;

public class CamelSteps {

@CitrusResource
private TestRunner runner;

@CitrusFramework
private Citrus citrus;

private CamelContext camelContext;

private String requestBody;
private String responseBody;

@Given("^(?:Default|New) Camel context$")
public void defaultContext() {
destroyCamelContext();
camelContext();
}

@Given("^New Spring Camel context$")
public void camelContext(String beans) {
destroyCamelContext();

try {
ApplicationContext ctx = new GenericXmlApplicationContext(new ByteArrayResource(beans.getBytes(StandardCharsets.UTF_8)));
camelContext = ctx.getBean(SpringCamelContext.class);
camelContext.start();
} catch (Exception e) {
throw new IllegalStateException("Failed to start Spring Camel context", e);
}
}

@Given("^Camel route ([^\"\\s]+)\\.xml")
public void camelRouteXml(String id, String route) throws Exception {
String routeXml;

if (route.startsWith("<route>")) {
routeXml = String.format("<route id=\"%s\" xmlns=\"http://camel.apache.org/schema/spring\">", id) + route.substring("<route>".length());
} else if (route.startsWith("<route")) {
routeXml = route;
} else {
routeXml = String.format("<route id=\"%s\" xmlns=\"http://camel.apache.org/schema/spring\">", id) + route + "</route>";
}

RoutesDefinition routeDefinition = ModelHelper.loadRoutesDefinition(camelContext(), new ByteArrayInputStream(routeXml.getBytes(StandardCharsets.UTF_8)));

for (RouteDefinition definition : routeDefinition.getRoutes()) {
camelContext().addRouteDefinition(definition);
camelContext().startRoute(definition.getId());
}
}

@Given("^Camel route ([^\"\\s]+)\\.groovy")
public void camelRouteGroovy(String id, String route) throws Exception {
RouteBuilder routeBuilder = new RouteBuilder(camelContext()) {
@Override
public void configure() throws Exception {
ImportCustomizer ic = new ImportCustomizer();
ic.addStarImports("org.apache.camel");

CompilerConfiguration cc = new CompilerConfiguration();
cc.addCompilationCustomizers(ic);
cc.setScriptBaseClass(DelegatingScript.class.getName());

ClassLoader cl = Thread.currentThread().getContextClassLoader();
GroovyShell sh = new GroovyShell(cl, new Binding(), cc);

DelegatingScript script = (DelegatingScript) sh.parse(route);

// set the delegate target
script.setDelegate(this);
script.run();
}

@Override
protected void configureRoute(RouteDefinition route) {
route.id(id);
}
};

camelContext().addRoutes(routeBuilder);
}

@Given("^start route (.+)$")
public void startRoute(String routeId) {
runner.camel(action -> action.context(camelContext().adapt(ModelCamelContext.class))
.start(routeId));
}

@Given("^stop route (.+)$")
public void stopRoute(String routeId) {
runner.camel(action -> action.context(camelContext().adapt(ModelCamelContext.class))
.stop(routeId));
}

@Given("^remove route (.+)$")
public void removeRoute(String routeId) {
runner.camel(action -> action.context(camelContext().adapt(ModelCamelContext.class))
.remove(routeId));
}

@Given("^request body$")
public void setRequestBodyMultiline(String body) {
setRequestBody(body);
}

@Given("^request body: (.+)$")
public void setRequestBody(String body) {
this.requestBody = body;
}

@When("^send to route ([^\"\\s]+)$")
public void sendExchange(String endpointUri) {
runner.send(action -> action.endpoint(camelEndpoint(endpointUri))
.payload(requestBody));
}

@When("^send to route ([^\"\\s]+) body$")
public void sendExchangeMultilineBody(String endpointUri, String body) {
sendExchangeBody(endpointUri, body);
}

@When("^send to route ([^\"\\s]+) body: (.+)$")
public void sendExchangeBody(String endpointUri, String body) {
runner.send(action -> action.endpoint(camelEndpoint(endpointUri))
.payload(body));
}

@Then("^(?:expect|verify) body received$")
public void setResponseBodyMultiline(String body) {
setResponseBody(body);
}

@Then("^(?:expect|verify) body received: (.+)$")
public void setResponseBody(String body) {
this.responseBody = body;
}

@Then("^receive from route ([^\"\\s]+)$")
public void receiveExchange(String endpointUri) {
runner.receive(action -> action.endpoint(camelEndpoint(endpointUri))
.payload(responseBody));
}

@Then("^receive from route ([^\"\\s]+) body$")
public void receiveExchangeBodyMultiline(String endpointUri, String body) {
receiveExchangeBody(endpointUri, body);
}
@Then("^receive from route ([^\"\\s]+) body: (.+)$")
public void receiveExchangeBody(String endpointUri, String body) {
runner.receive(action -> action.endpoint(camelEndpoint(endpointUri))
.payload(body));
}

// **************************
// Helpers
// **************************

private CamelEndpoint camelEndpoint(String endpointUri) {
CamelEndpointConfiguration endpointConfiguration = new CamelEndpointConfiguration();
endpointConfiguration.setCamelContext(camelContext());
endpointConfiguration.setEndpointUri(endpointUri);
return new CamelEndpoint(endpointConfiguration);
}

private CamelContext camelContext() {
if (camelContext == null) {
try {
camelContext = new DefaultCamelContext();
camelContext.start();
} catch (Exception e) {
throw new IllegalStateException("Failed to start default Camel context", e);
}
}

return camelContext;
}

private void destroyCamelContext() {
try {
if (camelContext != null) {
camelContext.stop();
camelContext = null;
}
} catch (Exception e) {
throw new IllegalStateException("Failed to stop existing Camel context", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.yaks.testing.camel;

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;

/**
* @author Christoph Deppisch
*/
@RunWith(Cucumber.class)
@CucumberOptions(
strict = true,
glue = { "dev.yaks.testing.camel" },
plugin = { "com.consol.citrus.cucumber.CitrusReporter" } )
public class CamelFeatureTest {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cucumber.api.java.ObjectFactory=cucumber.runtime.java.CitrusObjectFactory
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Feature: Camel context

Background:
Given New Spring Camel context
"""
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext id="helloContext" xmlns="http://camel.apache.org/schema/spring">
<route id="helloRoute">
<from uri="direct:hello"/>
<to uri="log:dev.yaks.testing.camel?level=INFO"/>
<split>
<tokenize token=" "/>
<to uri="seda:tokens"/>
</split>
</route>
</camelContext>
</beans>
"""

Scenario: Hello Context
Given request body: Hello Camel!
When send to route direct:hello
Then expect body received: Hello
And receive from route seda:tokens
Then expect body received: Camel!
And receive from route seda:tokens
Loading

0 comments on commit 7bbc4e5

Please sign in to comment.