I have a Camel Route which uses CDI to load a properties file from the JBoss configuration directory ...works perfect.
What I need to do is load one of the properties that are loaded in
an Arquillian integration test I am writing.
Example:
Content of Fiddler.properties file in the JBoss configuration directory
silly.value = Laughing
serious.value = politics
Example Producer class to load properties
/**
* Create the Camel properties component using CDI #Produces
*/
#Produces
#Named("properties")
PropertiesComponent propertiesComponent() {
final PropertiesComponent component = new PropertiesComponent();
// load JBoss properties file
component.setLocation(
"file:${jboss.server.config.dir}/fiddler.properties"
);
return component;
}
A given property from the Fiddler.properties file is now available in the main Camel route as {{silly.value}} or {{serious.value}}
Problem:
What I would like to do is load/reference one of these property values from my Arquillian Integration Test … probably in the #BeforeClass method …something like below:
#RunWith(Arquillian.class)
public class MainRouteIT {
.
.
Boolean allOK = false;
#BeforeClass
public static void setupTest() throws Exception {
allOK = new testCheck(
{{silly.value}}, {{serious.value}}
);
.
.
Any idea if something like this is possible in Camel within an Arquillian test ?
Here is the solution we are using (but without Arquillian):
First define a CDI alternative for the Camel "properties" component, which will use testing property values.
Then annotate your unit test in order to use the alternate producers of Camel components.
#Alternative
public class CamelAlternatives {
#Produces
#ApplicationScoped
#Named("properties")
public PropertiesComponent propertiesComponent() {
PropertiesComponent component = new PropertiesComponent();
component.setLocations( Arrays.asList("classpath:common.properties", "classpath:testing.properties") );
return component;
}
#RunWith(CamelCdiRunner.class)
#Beans(alternatives = {CamelAlternatives.class})
public class MyUnitTest {
...
}
Related
I'd like to know if it is possible to use Project Reactor with Apache Camel, so applications be fully reactive and non-blocking IO. I'd like to know how does the Project Reactor support works when integrating other Apache Camel's components.
Can I read for example from S3 reactively (therefore I'll need to use the Async S3 client behind the scenes)? Or will I block when reading from S3 and then just create a Flux out of what has been returned?
Where reactiveness is needed, you should use the relevant spring and reactor libraries. there are pseudo camel code also u can db call in camel bean or processors etc
#RestController
#RequestMapping(value = "/api/books")
#RequiredArgsContructor
public class HomeController {
private final BookRepository bookRepository;
private final ProducerTemplate template
#GetMapping("")
public Flux<Book> getHome() {
List <Book> books=bookRepository.findAll();
X ret = template.requestBody("direct:something", books, X.class);
}
}
#Component
public class SomeRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("direct:something")
.process(e-> {
List<Book> books = e.getIn.getBody(List.class)
// some logic
e.getIn.setBody(new X( ))
})
}
I am using camel-cdi and it is injecting the CamelContext, detecting all the routes in project.
But I want a CamelContext with a registry because I have some components that I use in camel routes like shown below.
SimpleRegistry registry = new SimpleRegistry();
registry.put("actionProcessor", actionProcessor);
registry.put("jpa", jpaComponent);
registry.put("jtaTransactionManager", platformTransactionManager);
CamelContext camelContext = new DefaultCamelContext(registry);
When I inject CamelContext the components like actionProcess, jpa are not recognized. when in my Route I have
.to("bean:actionProcessor?method=myMethod(${body})")
but my bean does not get executed.
I documentation I read use # before components name which are in registry but still it is not working.
Please suggest how can I achieve this using camel-cdi.
Did you already try with creating a CdiCamelContext (a subclass of DefaultCamelContext) ?
Otherwise, a more elegant would be to annotate your various classes, eg:
#Named("actionProcessor")
public class MyActionProcessor{
...
}
We have been using this for years without any problem
public class ContextFactory {
#Produces
#ApplicationScoped
#ContextName("Demo")
static final CamelContext createContext() {
CdiCamelContext context = new CdiCamelContext();
context.setStreamCaching(true);
context.disableJMX();
return context;
}
}
#ContextName("Demo")
public class MyRouteBuilder extends RouteBuilder {
from("...")
.to("bean:actionProcessor?method=myMethod")
}
#Named("actionProcessor")
public class MyActionProcessor{
public void myMethod(#Body String body) {}
}
Of course, in order to work, you need to activate the JEE bean discovery (=add a "beans.xml" file in META-INF or WEB-INF) !
I build camel application using org.apache.camel.main.Main class like this:
public static void main(String... args) throws Exception {
Main main = new Main();
main.enableHangupSupport();
main.addRouteBuilder(new MainRoute());
main.addRouteBuilder(ConfigurationRoute.getloginRoute());
main.run(args);
}
how to include properties file (src/main/resources/prop.properties) in the code?
Do you mean to configure the Camel properties component for properties placeholders?
http://camel.apache.org/using-propertyplaceholder.html
We could probably make this easier to configure on the Main class so you can configure it to one or more properties files.
I have logged a ticket to make this easier: https://issues.apache.org/jira/browse/CAMEL-10255
What you need to do is to
PropertiesComponent pc = new PropertiesComponent();
pc.setLocation("prop.properties");
main.bind("properties, pr);
Where you create the component and configure it. And then bind it with the id properties.
The location is automatic loaded from the classpath, so you do not need src/main/resources as prefix.
I'm using the Main class from Apache Camel to run it as standalone.
I need to use the JMS component so I have to add it to the CamelContext instance used by the Main class.
Of course I need to do that before calling main.run(args) method.
The problem is the following ...
Using main.getCamelContexts().get(0) returns an index out of bounds exception.
Using main.getOrCreateCamelContext() returns a valid CamelContext instance named "camel-1" to which I'm able to add my JMS component but .... when I execute main.run(args), another CamelContext named "camel-2" is used !
The only way I found to add my JMS component is to use :
main.bind("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
Is this the only way or the CamelContext way should work ?
Thanks,
Paolo.
You can provide completely own camel context to be used. To achieve that you can inherit org.apache.camel.main.Main and override only one method
protected Map<String, CamelContext> getCamelContextMap()
Here is the example of inherited body:
#Override
protected Map<String, CamelContext> getCamelContextMap() {
Map<String, CamelContext> camelContextMap = new HashMap<>();
DefaultCamelContext camelContext = new DefaultCamelContext();
camelContext.setName("MyContext");
// Add your context configuration here
camelContextMap.put("connectorContext", camelContext);
return camelContextMap;
}
In general it is better to create context map not in the "getCamelContextMap()" inherited method but somewhere in the constructor.
Old Question, but was able to figure it out - tried with camel 2.17.x version
private void runMyExample() {
//Add a Main Listener
main.addMainListener(new MyMainListener);
main.run();
}
public static class MyMainListener extends MainListenerSupport {
#Override
public void afterStart(MainSupport main) {
System.out.println("MainExample with Camel is now started!");
//This is the right instance
CamelContext context = main.getCamelContexts().get(0);
}
#Override
public void beforeStop(MainSupport main) {
System.out.println("MainExample with Camel is now being stopped!");
}
}
Regards,
R.
How is that for a lot of acronyms!
I am having trouble testing GWT's RPC mechanism using GWT's GWTTestCase. I created a class for testing using the junitCreator tool included with GWT. I am attempting to test using the built in Google App Engine using the created "hosted mode" testing profile created by junitCreator. When I run the test, I keep getting errors saying things like
Starting HTTP on port 0
HTTP listening on port 49569
The development shell servlet received a request for 'greet' in module 'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml'
[WARN] Resource not found: greet; (could a file be missing from the public path or a <servlet> tag misconfigured in module com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml ?)
com.google.gwt.user.client.rpc.StatusCodeException: Cannot find resource 'greet' in the public path of module 'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit'
I hope that someone somewhere has successfully run junit test (using GWTTestCase or just plain TestCase) that will allow for the testing of gwt RPC. If this is the case, could you please mention the steps you took, or better yet, just post code that works. Thanks.
SyncProxy allows you to make GWT RPC call from Java. So you can test your GWT RPC with regular Testcase (and faster than GwtTestcase)
See
http://www.gdevelop.com/w/blog/2010/01/10/testing-gwt-rpc-services/
http://www.gdevelop.com/w/blog/2010/03/13/invoke-gwt-rpc-services-deployed-on-google-app-engine/
I got this working. This answer assume's you're using Gradle, but this could easily be adopted to run from ant. First, you'll have to make sure that you separate your GWT tests from your regular JUnit tests. I created 'tests/standalone' for the regular tests, and 'tests/gwt' for my GWT tests. I still get 1 single HTML report in the end that has all of the info.
Next, you need to make sure JUnit is part of your ant classpath, as described here:
http://gradle.1045684.n5.nabble.com/Calling-ant-test-target-fails-with-junit-classpath-issue-newbie-td4385167.html
Then, use something similar to this to compile your GWT tests and run them:
task gwtTestCompile(dependsOn: [compileJava]) << {
ant.echo("Copy the test sources in so they're part of the source...");
copy {
from "tests/gwt"
into "$buildDir/src"
}
gwtTestBuildDir = "$buildDir/classes/test-gwt";
(new File(gwtTestBuildDir)).mkdirs()
(new File("$buildDir/test-results")).mkdirs()
ant.echo("Compile the tests...");
ant.javac(srcdir: "tests/gwt", destdir: gwtTestBuildDir) {
classpath {
pathElement(location: "$buildDir/src")
pathElement(location: "$buildDir/classes/main")
pathElement(path: configurations.runtime.asPath)
pathElement(path: configurations.testCompile.asPath)
pathElement(path: configurations.gwt.asPath)
pathElement(path: configurations.gwtSources.asPath)
}
}
ant.echo("Run the tests...");
ant.junit(haltonfailure: "true", fork: "true") {
classpath {
pathElement(location: "$buildDir/src")
pathElement(location: "$buildDir/classes/main")
pathElement(location: gwtTestBuildDir)
pathElement(path: configurations.runtime.asPath)
pathElement(path: configurations.testCompile.asPath)
pathElement(path: configurations.gwt.asPath)
pathElement(path: configurations.gwtSources.asPath)
}
jvmarg(value: "-Xmx512m")
jvmarg(line: "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005")
test(name: "com.onlyinsight.client.LoginTest", todir: "$buildDir/test-results")
formatter(type: "xml")
}
}
test.dependsOn(gwtTestCompile);
Finally, here's a simple GWT test:
public class LoginTest extends GWTTestCase
{
public String getModuleName()
{
return "com.onlyinsight.ConfModule";
}
public void testRealUserLogin()
{
UserServiceAsync userService = UserService.App.getInstance();
userService.login("a", "a", new AsyncCallback<User>()
{
public void onFailure(Throwable caught)
{
throw new RuntimeException("Unexpected Exception occurred.", caught);
}
public void onSuccess(User user)
{
assertEquals("a", user.getUserName());
assertEquals("a", user.getPassword());
assertEquals(UserRole.Administrator, user.getRole());
assertEquals("Test", user.getFirstName());
assertEquals("User", user.getLastName());
assertEquals("canada#onlyinsight.com", user.getEmail());
// Okay, now this test case can finish.
finishTest();
}
});
// Tell JUnit not to quit the test, so it allows the asynchronous method above to run.
delayTestFinish(10 * 1000);
}
}
If your RPC instance doesn't have a handy getInstance() method, then add one:
public interface UserService extends RemoteService {
public User login(String username, String password) throws NotLoggedInException;
public String getLoginURL(OAuthProviderEnum provider) throws NotLoggedInException;
public User loginWithOAuth(OAuthProviderEnum provider, String email, String authToken) throws NotLoggedInException;
/**
* Utility/Convenience class.
* Use UserService.App.getInstance() to access static instance of UserServiceAsync
*/
public static class App {
private static final UserServiceAsync ourInstance = (UserServiceAsync) GWT.create(UserService.class);
public static UserServiceAsync getInstance()
{
return ourInstance;
}
}
}
I hope that helps.