CamelCorrelationID/JMS CorrelationID implementation - apache-camel

I am confused how to implement CamelCorrelationID/JMSCorrelationID in a way where each application listen to its own response from server using messaging system. The queues are shared in this scenario. I have implemented my own CorrelationID to maintain the state of application. here I am using two client applications (Client-A and Client-B) sending/receiving the request to/from server
Currently both applications are reading each other responses from server, instead each application should listens to its own response based on CorrelationID passed in the header of request message.
Need help to resolve this.
Below are the code details:
Client-A code:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.camel.a</groupId>
<artifactId>CorrelationId-A</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>CorrelationId-A</name>
<description>Understanding CorrelationId</description>
<properties>
<java.version>1.8</java.version>
<camel.version>3.11.0</camel.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-amqp-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ClientARequestRoute.java
package com.camel.a.route;
import java.util.UUID;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class ClientARequestRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("timer://runOnce?repeatCount=1")
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
UUID uuid = UUID.randomUUID();
String uniqueId = uuid.toString();
String testMsg = "Sending message from Client A with Unique Id as - " + uniqueId;
exchange.getIn().setHeader(Exchange.CORRELATION_ID, uniqueId);
exchange.getIn().setBody(testMsg, String.class);
}
})
.log("${body}")
.to("amqp:queue:RequestQueue");
}
}
ResponseServerRoute.java
package com.camel.a.route;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class ResponseServerRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("amqp:queue:ResponseQueue")
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
String uniqueId = (String)exchange.getIn().getHeader(Exchange.CORRELATION_ID);
System.out.println("Received Correlation Id - " + uniqueId);
String msgReceived = (String) exchange.getIn().getBody(String.class);
exchange.getIn().setBody(msgReceived);
}
})
.log("${body}")
.end();
}
}
Client-B code:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.camel.b</groupId>
<artifactId>CorrelationId-B</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>CorrelationId-B</name>
<description>Understanding CorrelationId</description>
<properties>
<java.version>1.8</java.version>
<camel.version>3.11.0</camel.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-amqp-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ClientBRequestRoute.java
package com.camel.b.route;
import java.util.UUID;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
#Component
public class ClientBRequestRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("timer://runOnce?repeatCount=1")
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
UUID uuid = UUID.randomUUID();
String uniqueId = uuid.toString();
String testMsg = "Sending message from Client B with Unique Id as - " + uniqueId;
exchange.getIn().setHeader(Exchange.CORRELATION_ID, uniqueId);
exchange.getIn().setBody(testMsg, String.class);
}
})
.log("${body}")
.to("amqp:queue:RequestQueue");
}
}
ResponseServerRoute.java
package com.camel.b.route;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class ResponseServerRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("amqp:queue:ResponseQueue")
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
String uniqueId = (String)exchange.getIn().getHeader(Exchange.CORRELATION_ID);
System.out.println("Received Correlation Id - " + uniqueId);
String msgReceived = (String) exchange.getIn().getBody(String.class);
exchange.getIn().setBody(msgReceived);
}
})
.log("${body}")
.end();
}
}

Related

Springboot-MongoDb required a bean of type could not be found

I'm trying to connect my Springboot aplication to MongoDb. When i ran my application and i got this error:
Description:
Field userRepo in com.universitem.service.Impl.UserDetailsServiceImpl required a bean of type 'com.universitem.repository.UserRepository' that could not be found.
Action:
Consider defining a bean of type 'com.universitem.repository.UserRepository' in your configuration.
application.properties file:
spring.jpa.hibernate.ddl-auto=update
spring.data.mongodb.uri= /includes the uri
spring.data.mongodb.database=test
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
universitem.app.secret=UniversityToken
universitem.expires.in=120000
refresh.token.expires.in=604800
Main file :
#SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
#EnableJpaRepositories(basePackages = {"com.universitem.repository"})
public class UniversitemApplication {
public static void main(String[] args) {
SpringApplication.run(UniversitemApplication.class, args);
}
}
Security Configuration file:
#Configuration
#EnableWebSecurity
#Data
public class SecurityConfig {
private UserDetailsServiceImpl userDetailsService;
private JwtAuthenticationEntryPoint handler;
public SecurityConfig(UserDetailsServiceImpl userDetailsService, JwtAuthenticationEntryPoint handler) {
this.userDetailsService = userDetailsService;
this.handler = handler;
}
#Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(handler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/comment/getAllUniversityComment{universityId}")
.permitAll()
.antMatchers(HttpMethod.GET, "/university/getAll")
.permitAll()
.antMatchers(HttpMethod.POST, "/userType/add")
.permitAll()
.antMatchers(HttpMethod.POST, "/universityType/add")
.permitAll()
.antMatchers(HttpMethod.GET, "/userType/getAll")
.permitAll()
.antMatchers("/userAuth/**")
.permitAll()
.anyRequest().authenticated();
httpSecurity.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
}
User Repository file:
#Repository
public interface UserRepository extends JpaRepository<User,Long> {
User findByUserName(String userName);
User findByUserMail(String userMail);
}
User Details Service Implementation file:
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserRepository userRepo;
#Override
public UserDetails loadUserByUsername(String userMail) throws UsernameNotFoundException {
User user =userRepo.findByUserMail(userMail);
return JwtUserDetails.create(user);
}
public UserDetails loadUserById(Long userId) {
User user = userRepo
.findById(userId).get();
return JwtUserDetails.create(user);
}
}
pom.xml file:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I tried to add scanBasePackages to #SpringBootApplication like below. Actually database has been started but when i tried to sent request i got 404 Not Found error on postman.
#SpringBootApplication(scanBasePackages = {"com.universitem.repository"}, exclude = {SecurityAutoConfiguration.class})

How to configure connection factor for Camel SJMS2 Component

I'm confused about the best way to configure the SJMS2 component. I'm using camel-spring-boot-starter in a simple test application and trying to write from a ProducerTemplate to ActiveMQ Artemis using the SJMS2 Camel Component. The component documentation says it handles things like connection caching and such which I would normally configure in my ConnectionFactory bean, so I'm getting the sense that I should defining less in my Configuration than I would without using Camel.
The documentation seems to lack a clear example of how to configure an jsms2 route and its ConnectionFactory when using Camel Spring. Is there a good example of this somewhere or could someone show me how that would look? Here's my current test application:
Spring Boot Application:
#SpringBootApplication
public class WebhookpublisherApplication implements CommandLineRunner {
#Autowired
private ProducerTemplate producerTemplate;
public static void main(String[] args) {
SpringApplication.run(WebhookpublisherApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
producerTemplate.sendBody("direct:test", "testBody");
}
}
Route:
#Component
public class RestToJmsRoute extends RouteBuilder {
#Override
public void configure() {
from("direct:test")
.log("Recieved a test body: ${body}")
.to("sjms2:topic:test-topic");
}
}
JMS Config (which is clearly not being used by the Camel component)
#Configuration
public class JmsConfig {
#Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
return new ActiveMQConnectionFactory("tcp://localhost:61616");
}
}
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>cameljmstest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cameljmstest</name>
<description>test app</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-rest</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-sjms2</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The above is resulting in the following exception:
Caused by: java.lang.IllegalArgumentException: ConnectionResource or
ConnectionFactory must be configured for sjms2://test-topic
I ended up adding the following configuration class:
#Configuration
public class CamelContextConfig {
#Bean
public CamelContextConfiguration contextConfiguration() {
return new CamelContextConfiguration() {
#Override
public void beforeApplicationStart(CamelContext context) {
Sjms2Component component = new Sjms2Component();
ActiveMQConnectionFactory activeMqConnectionFactory = new ActiveMQConnectionFactory("tcp://myArtemisHost:61616");
activeMqConnectionFactory.setUser("user");
activeMqConnectionFactory.setPassword("pass");
component.setConnectionFactory(activeMqConnectionFactory);
context.addComponent("sjms2", component);
}
#Override
public void afterApplicationStart(CamelContext camelContext) {
}
};
}
}
and then I changed my pom dependencies to these:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-sjms2-starter</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

#Test is not executing - If I add TestNG Listener in test xml file, my #Test methods are not executing

I'm using TestNG and for reporting using extent report. I'm trying to add TestNG Listeners to perform some operation on Success and on Failure. I have created a Test Listener class and mentioned listener in suite file.Issue is Test is not executing and console says Test run =0 ; If is remove listener tag from suite xml file, it works like charm.
Listener class
public class TestListener implements ITestListener
{
#Override
public void onTestStart(ITestResult result)
{
// TODO Auto-generated method stub
System.out.println("OnTestStart");
}
#Override
public void onTestSuccess(ITestResult result)
{
// TODO Auto-generated method stub
Reporter.log(Status.INFO, "Passed");
}
#Override
public void onTestFailure(ITestResult result)
{
// TODO Auto-generated method stub
Reporter.log(Status.INFO, "Failed");
}
}
Base Test
public class BaseTest
{
#BeforeSuite
public void preStep(ITestContext txt)
{
System.out.println("in before suite");
Reporter.startReport(txt);
System.out.println("out");
}
#BeforeMethod(alwaysRun=true)
public void setUp()
{
System.out.println("Before Method");
Reporter.setup();
}
#AfterMethod
public void closeUp(ITestResult tr)
{
System.out.println("After Method");
}
#AfterSuite
public void postStep()
{
System.out.println("After Suite");
}
}
Test class
public class TestScripts extends BaseTest
{
#Test
#Parameters("Browser")
public void loginScenario(String browser)
{
LoginPageSteps lp = new LoginPageSteps(browser);
lp.loginScenario();
}
#Test
#Parameters("Browser")
public void a(String browser)
{
Reporter.log(Status.PASS, "A Passed");
}
#Test
#Parameters("Browser")
public void b(String browser)
{
Reporter.log(Status.ERROR, "B Failed");
}
#Test
#Parameters("Browser")
public void c(String browser)
{
Reporter.log(Status.ERROR, "C Failed");
}
}
Suite File
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="10" name="Default Suite" parallel="tests">
<listeners>
<listener class-name="testng.framework.utilities.TestListener"/>
</listeners>
<test thread-count="10" name="GUI" parallel="tests">
<classes>
<class name="testng.alltest.TestScripts">
<parameter name="Browser" value="Chrome"/>
<methods>
<include name="a"/>
<include name="b"/>
<include name="c"/>
<include name="loginScenario"/>
</methods>
</class>
</classes>
</test>
</suite>
Output
Kindly correct me what i'm missing out, Thanks in advance
POM.xml
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>ORORA</groupId>
<artifactId>UIAutomation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>UIAutomation</name>
<url>http://maven.apache.org</url>
<developers>
<developer>
<id>Deepak Mahalingam</id>
<name>Deepak</name>
<email>mahalingamd#hcl.com</email>
<organization>HCL</organization>
<roles>
<role>Automation Tester</role>
</roles>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>TestSuite\TestDesktop.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<mainClass>testng.framework.utilities.BuildTestXML</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.14.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>4.0.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>3.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
It seems that there is issue with your Listener class and Reporter
class import statement .
If your are using Reporter class of TestNG then there is no such
method as "setup" or start
I am able to run the script by modifying your TestListener and BaseTest class as follows:
package stackoverflow;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class TestListener implements ITestListener {
#Override
public void onTestStart(ITestResult iTestResult) {
System.out.println("onTestStart");
}
#Override
public void onTestSuccess(ITestResult iTestResult) {
System.out.println("onTestSuccess");
}
#Override
public void onTestFailure(ITestResult iTestResult) {
System.out.println("onTestFailure");
}
#Override
public void onTestSkipped(ITestResult iTestResult) {
System.out.println("onTestSkipped");
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult iTestResult) {
System.out.println("onTestFailedButWithinSuccessPercentage");
}
#Override
public void onStart(ITestContext iTestContext) {
System.out.println("onTestFailedButWithinSuccessPercentage");
}
#Override
public void onFinish(ITestContext iTestContext) {
System.out.println("onFinish");
}
}
My Base Test Class :
package stackoverflow;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
public class BaseTest {
#BeforeSuite
public void preStep(ITestContext txt)
{
System.out.println("in before suite");
System.out.println("out");
}
#BeforeMethod(alwaysRun=true)
public void setUp()
{
System.out.println("Before Method");
}
#AfterMethod
public void closeUp(ITestResult tr)
{
System.out.println("After Method");
}
#AfterSuite
public void postStep()
{
System.out.println("After Suite");
}
}
My TestNg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="10" name="Default Suite" parallel="tests">
<listeners>
<listener class-name="listener.TestListener"/>
</listeners>
<test thread-count="10" name="GUI" parallel="tests">
<classes>
<class name="stackoverflow.TestScripts">
<parameter name="Browser" value="Chrome"/>
<methods>
<include name="a"/>
<include name="b"/>
<include name="c"/>
<include name="loginScenario"/>
</methods>
</class>
</classes>
</test>
</suite>

Is there a recommended way for Solr 3.6 JUnit testing?

I wonder if there is any best practice for junit testing of Solr 3.6. I want to automate testing of the Solr schema. Earlier posts mentioned the EmbeddedSolrServer. This class seems to have been abandoned from any version between 1.4 an 3.6. I use Spring 3.0.x and Maven for the project.
The options I considered are:
writing a Junit Test Runner
put the jetty startup code in the #Before or #BeforeClass method
start a solr server in maven (probably not a good option)
put some code in the spring test-context
I've used something similar to what's on this page to run these kinds of tests, all done with EmbeddedSolrServer on Solr 3.4.0. This is a simple approach, but if you want to automate Solr schema testing, it could be enough and isn't hard to implement.
It basically boils down to:
Adding references to junit, solr-core, slf4j-simpleand servlet-apito your pom.xml:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<!-- dependencies needed for Solr integration test-->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-core</artifactId>
<version>1.4.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
And as an example test case, he adds this:
import java.io.IOException;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.SolrParams;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SolrSearchConfigTest extends AbstractSolrTestCase {
private SolrServer server;
#Override
public String getSchemaFile() {
return "solr/conf/schema.xml";
}
#Override
public String getSolrConfigFile() {
return "solr/conf/solrconfig.xml";
}
#Before
#Override
public void setUp() throws Exception {
super.setUp();
server = new EmbeddedSolrServer(h.getCoreContainer(), h.getCore().getName());
}
#Test
public void testThatNoResultsAreReturned() throws SolrServerException {
SolrParams params = new SolrQuery("text that is not found");
QueryResponse response = server.query(params);
assertEquals(0L, response.getResults().getNumFound());
}
#Test
public void testThatDocumentIsFound() throws SolrServerException, IOException {
SolrInputDocument document = new SolrInputDocument();
document.addField("id", "1");
document.addField("name", "my name");
server.add(document);
server.commit();
SolrParams params = new SolrQuery("name");
QueryResponse response = server.query(params);
assertEquals(1L, response.getResults().getNumFound());
assertEquals("1", response.getResults().get(0).get("id"));
}
}
edit: I haven't used Solr in quite a while, but I think this could still be a good starting point.
This is my take on it. It doesn't extend AbstractSolrTestCase, just a regular test class.
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.core.CoreContainer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class EmbeddedSolrServerTest {
private static final int SUCCESS = 0;
private final String indexLocation = "tomcat7/apps/apache-solr-3.6.0";
private EmbeddedSolrServer server;
#Before
public void setUp() throws Exception {
System.setProperty("solr.solr.home", indexLocation);
CoreContainer coreContainer = new CoreContainer.Initializer().initialize();
server = new EmbeddedSolrServer(coreContainer, "collection1");
}
#After
public void tearDown() throws Exception {
server.shutdown();
removeIndexDirectory();
}
#Test
public void testSolrSchema01() throws Exception {
SolrInputDocument doc1 = new SolrInputDocument();
doc1.addField("id", "123");
doc1.addField("something_txt", "super wombat");
UpdateResponse ur = server.add(doc1);
assertThat(ur.getStatus(), is(SUCCESS));
server.commit();
QueryResponse response1 = server.query(new SolrQuery("*:*"));
assertThat(response1.getResults().getNumFound(), is(1L));
QueryResponse response2 = server.query(new SolrQuery("something_txt:*wombat*"));
assertThat(response2.getResults().getNumFound(), is(1L));
}
private void removeIndexDirectory() throws IOException {
File indexDir = new File(indexLocation, "data/index");
FileUtils.deleteDirectory(indexDir);
}
}
My POM has the following dependencies:
<properties>
<solr.version>3.6.0</solr.version>
<httpcomponents.version>4.3.2</httpcomponents.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>${solr.version}</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-core</artifactId>
<version>${solr.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpcomponents.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>${httpcomponents.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
I've set up a separate project to keep all my Solr config in and run tests against it. The directory structure is:
solr-test
|--src
| |--test
|--tomcat7
` |--apps
|--apache-solr-3.6.0
|--conf
|--data
|--index
This seems to work well for me. This set up will also let you write tests using HttpSolrServer to test a remote server's schema.
Also, note the server.commit() call in the middle of the test. This needs to be there otherwise the Solr transaction isn't complete and the new document won't be visible.
I'm using https://github.com/moliware/travis-solr for my tests, maybe it's useful for you too.

Mina route on servicemix - Error executing command: java.lang.NullPointerException

I've created a very simple camel route using the mina component. This route actually uses a custom Codec and is packaged as osgi bundle. Whenever I deploy it to servicemix (apache-servicemix-4.4.1-fuse-03-06) the bundle is not getting the Active state but Installed. And of course when I try to start it I'm getting a "Error executing command: java.lang.NullPointerException" from the console, but nothing in the logs...
Can somebody help me make this work I can't figure out what's happening... Is this a packaging issue? I guess it has something to do with my codec loading, but I'm stuck here now.
Here is my XML route
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="myCodec" class="test.net.mina.codec.MyMinaCodec" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="mina:tcp://localhost:9000?sync=true&codec=#myCodec" />
<to uri="log:IncomingMsg" />
</route>
</camelContext>
</beans>
Here is my codec factory
public class MyMinaCodec implements
ProtocolCodecFactory {
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return new MyMinaDecoder();
}
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return new ProtocolEncoder() {
public void encode(IoSession arg0, Object arg1, ProtocolEncoderOutput arg2) throws Exception {
}
public void dispose(IoSession arg0) throws Exception {
}
};
}
}
My codec implementation:
public class MyMinaDecoder extends CumulativeProtocolDecoder {
public static final int MSG_HEADER_SIZE = 14;
#Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
// try to read the message header
if (in.remaining() >= MSG_HEADER_SIZE) {
out.write(readsUnsignedBytesToString(in, MSG_HEADER_SIZE));
return true;
} else {
// not enough data
return false;
}
}
private String readsUnsignedBytesToString(IoBuffer in, int length) {
char[] unsignedChars = new char[length];
for (int i = 0; i < length; i++) {
unsignedChars[i] = (char) in.getUnsigned();
}
return new String(unsignedChars);
}
}
And my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.servicemix.features</groupId>
<artifactId>features</artifactId>
<version>4.4.1-fuse-03-06</version>
</parent>
<groupId>test</groupId>
<artifactId>mina-test</artifactId>
<packaging>bundle</packaging>
<name>My MINA Test</name>
<version>0.1.6</version>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mina</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Description>${project.description}</Bundle-Description>
<Import-Package>*</Import-Package>
<Require-Bundle>org.apache.servicemix.bundles.mina</Require-Bundle>
<Export-Package>test.net.*</Export-Package>
<DynamicImport-Package></DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
Thanks for your help.
Francois
This is being discussed and answered here
http://fusesource.com/forums/thread.jspa?threadID=3776&tstart=0

Resources