I am working on spring rest app with camel routes. I need to create route for each rest calls and transfer data to another soap server.Here is my code snippet.
Rest Controller
public class CreateEmployeeController{
#Autowired
ProducerTemplate producerTemplate;
#RequestMapping (value = "/api/createEmployee",method = RequestMethod.POST)
public void createEmployee(#RequestBody Object employee) {
producerTemplate.sendBody("direct:createEmployee",employee);
}
Camel Configuration
#Configuration
#ComponentScan ("com.employee.restService")
public class RouteConfig extends CamelConfiguration {
}
Camel Route
#Configuration
#Component
public class CreateEmployeeRouter extends RouteBuilder {
#Override
public void configure() throws Exception {
from("direct:createEmployee")
.to("spring-ws:CreateEmployeeEndpointService");
}
}
Dependancy
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.19.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-cxf -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.19.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-spring-javaconfig -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-javaconfig</artifactId>
<version>2.19.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-spring-ws -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-ws</artifactId>
<version>2.19.2</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot</artifactId>
<version>2.19.2</version>
</dependency>
StackTrace
org.apache.camel.spring.boot.CamelSpringBootInitializationException:
org.apache.camel.FailedToCreateRouteException: Failed to create route
route1 at: >>> To[spring-ws:CreateEmployeeEndpointService] <<< in route:
Route(route1)[[From[direct:createEmployee]] -> [To[spring-ws... because of Failed to resolve endpoint: spring-ws://CreateEmployeeEndpointService due to: No component found with scheme: spring-ws
at org.apache.camel.spring.boot.RoutesCollector.onApplicationEvent(RoutesCollector.java:225) ~[camel-spring-boot-2.19.2.jar:2.19.2]
Please help me if I am wrong.
Thanks in advance.
Switch your camel dependencies to 2.20.0, it worked for me
Related
Spring cloud-config server started with application.properties :
server.port:8888
spring.application.name=test-config-server
spring.cloud.config.server.git.uri=https://gitlab.com/pearsontechnology/gpt/sms/sms-micro-services/config-server.git
spring.cloud.config.server.git.default-label=develop
#Private repo. access credentials
spring.cloud.config.server.git.username=xxx
spring.cloud.config.server.git.password=xxxx
spring.cloud.config.server.git.clone-on-start=true
spring.cloud.config.profile=dev
On starting the config-client,
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
My version of spring boot, spring-cloud and dependencies are as follows from pom.xml :
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<java.version>17</java.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
application.prop of config-client :
spring.application.name=systems-lookup-service
spring.cloud.config.profile=dev
spring.config.import=optional:configserver:
server.port=8081
Properties related to Datasource like url etc. need to be taken from
systems-lookup-service-dev.properties hosted on Git.
custom.url=jdbc:oracle:thin:#localhost:1998/smscert
custom.username=smscert
custom.password=go#salt
custom.driverClassName=
And the DAO class in config-client accessing the db :
public class XXDaoImpl implements XXDao {
private JdbcTemplate jdbcTemplate;
#Autowired(required=false)
private DataSourceConfig config;
#Autowired
public SystemDaoImpl(JdbcTemplate jdbcTemplateIn){
final DataSource dataSource = DataSourceBuilder.create()
.driverClassName(config.getDriverClassName())
.url(config.getUrl())
.username(config.getUsername())
.password(config.getPassword())
.build();
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
...............
}
#Component
#ConfigurationProperties("custom")
public class DataSourceConfig {
private String url;
private String username;
private String password;
//#Value("${greeting.message}")
private String driverClassName;
....
}
I believe you follow the first boot-strapping for your central cloud registration to do so you need following artifact with in your client service pom file.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
Add the following properties to you client service property file application.prop
spring.application.name=systems-lookup-service
spring.cloud.config.uri=http://localhost:"cloud-config-port"
spring.profiles.active=dev
spring.config.import=optional:configserver:
With in main class on central cloud config add the annotation #EnableConfigServer and within it pom file add following artifact
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
append following properties to your central cloud config property file
spring.application.name=configuration-server
server.port=8780
management.endpoints.web.exposure.include=*
spring.cloud.config.server.git.uri=file:absoluthe-path
spring.cloud.config.server.git.clone-on-start=true
spring.cloud.config.allowOverride=true
Finally add your client service properties in your gitrepo with naming servicename-profile convention.
Extra point
You may consider to use spring cloud boss, for hot reloading the configs and not restarting services to handshake again, find out more in here.
Disabled auto-configuration of the data source by annotating client main with #SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
I am trying to start my application with Apache camel and Quarkus but it giving me below error:
At least one bean matched the required type and qualifiers but was marked as unused and removed during build
Removed beans:
- CLASS bean org.apache.camel.component.servlet.CamelHttpTransportServlet [types=[class javax.servlet.http.HttpServlet, interface java.io.Serializable, class org.apache.camel.http.common.CamelServlet, interface javax.servlet.ServletConfig, interface org.apache.camel.http.common.HttpRegistryProvider, class org.apache.camel.component.servlet.CamelHttpTransportServlet, class javax.servlet.GenericServlet, interface javax.servlet.Servlet], qualifiers=[#javax.enterprise.inject.Default(),
#javax.enterprise.inject.Any()]]
Required type: class org.apache.camel.component.servlet.CamelHttpTransportServlet
Required qualifiers: [#javax.enterprise.inject.Default()]
Solutions:
- Application developers can eliminate false positives via the #Unremovable annotation
- Extensions can eliminate false positives via build items, e.g. using the UnremovableBeanBuildItem
I am not sure what am I missing:
application.properties
camel.context.name=aiv
quarkus.camel.servlet.url-patterns = /rest/*
pom.xml
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-main</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-platform-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-log</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-timer</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-servlet</artifactId>
</dependency>
public class CamelRoute extends RouteBuilder {
#Override
public void configure() {
restConfiguration()
.component("servlet");
...
}
}
Please let me know what wrong am I doing?
Unless you genuinely need Servlet support for some reason, then you can rely on camel-quarkus-platform-http to handle the HTTP transport for the Camel REST DSL.
You're dependencies can be simplified to:
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-main</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-log</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-timer</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-rest</artifactId>
</dependency>
There's more information in the Camel Quarkus documentation:
https://camel.apache.org/camel-quarkus/latest/reference/extensions/platform-http.html
I am using "Spring Boot - 2.1.5.RELEASE" and "Spring framework - 5.1.7.RELEASE".
JMS listener annotation is not picking a message from a MQ queue. No error logs are rolling in my IntelliJ IDEA as well.
About my project - I am exposing a REST service which sends and receives a message from MQ (used JMSTemplate annotation). Till now it was working. Now I have to add another class which should listen for a queue. Hence added #JMSListener annotation which is not picking any message. Any insight will be really helpful.
The pom has below specified dependencies.
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>mq-jms-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
The class has below specified method.
import org.springframework.jms.annotation.JmsListener;
#Component
public class PickMyMessage {
#JmsListener(destination = "IN",containerFactory = "myFactory")
public void pullMyMessaage(String message){
System.out.println("Message is pulled..");
}
}
My main application has #EnableJMS annotation. In my application.yml file I have given below information.
ibm:
mq:
channel: MY.APP.SVRCONN
connName: 192.168.0.1(1415)
password: Pswd
queueManager: QM01
user: appsrv
My Bean class configs are
My JMS connection factory as below.
#Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
}
Not sure what else I am missing here. Any insight will be really helpful.
Instead of my existing project, if i create any simple demo project it is working as expected.
The class PickMyMessage is not a Spring bean, that's why Spring ignores it. Declare it as a #Bean or as a #Component.
May be there are further problems. But this is the first one that needs to be resolved.
I'm having problems to set up a global OkHttp interceptor for my #FeignClient beans. I'm not experiencing any error, but the interceptor is being ignored.
My understanding is that Spring Cloud's auto configuration should pick the OkHttpClient.Builder bean that I'm declaring and use it to create the underlying OkHttpClient instances, but I might be wrong about this.
Here are the relevant parts of my Spring app:
#SpringBootApplication
#EnableFeignClients(defaultConfiguration = FeignConfig.class)
#EnableCircuitBreaker
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class);
}
}
#Configuration
public class FeignConfig {
#Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor();
}
#Bean
public OkHttpClient.Builder okHttpClientBuilder(MyInterceptor interceptor) {
return new OkHttpClient.Builder().addInterceptor(interceptor);
}
}
public class MyInterceptor implements okhttp3.Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
System.out.println("Hey there, this is my request: " + request);
Response response = chain.proceed(request);
System.out.println("Hey there, this is my response: " + response);
return response;
}
}
The intercept method above is never called. I need MyInterceptor to be a Spring bean, because I need to inject other dependencies to it.
#FeignClient(name = "myClient", fallback = MyClientFallback.class)
public interface MyClient {
// method declarations
}
#Component
public class MyClientFallback implements MyClient {
// method fallback implementations
}
Here's the relevant part of my application.properties file:
feign.hystrix.enabled = true
feign.okhttp.enabled = true
ribbon.eureka.enabled = false
ribbon.eager-load.enabled = true
ribbon.eager-load.clients = myClient
myClient.ribbon.listOfServers = <IP_LIST>
myClient.ribbon.ServerListRefreshInterval = 10000
As you see from the properties declared above, I'm not using Eureka and I'm using Ribbon to load balance my rest client. I'm also using Hystrix to enable fallback responses and I have set the feign.okhttp.enabled property to true.
Below is the info about dependecies config and versions...
Spring Boot version is 2.0.3.RELEASE and Spring Cloud version is Finchley.SR1, while OkHttp version is 3.11.0.
In my pom.xml file, I have this spring-cloud-dependencies config:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencies>
</dependencyManagement>
I have also included the following Spring Boot and Spring Cloud dependencies, along with the OkHttp dependency:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
...
</dependencies>
You should provide an OkHttpClient bean as stated in the doc:
The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled or feign.httpclient.enabled to true, respectively, and having them on the classpath. You can customize the HTTP client used by providing a bean of either ClosableHttpClient when using Apache or OkHttpClient whe using OK HTTP.
https://github.com/OpenFeign/feign/blob/master/okhttp/src/main/java/feign/okhttp/OkHttpClient.java
The solution is to let Spring auto configuration do its job.
In order for that to happen, the following dependency must be removed from the pom.xml file:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
And the following one must be manually included:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
Once this is done, everything works as expected with the provided configuration.
Solution is to use OkHttpClient. Add pom.xml dependencies:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
and configure a bean:
#Configuration
public class FeignConfiguration {
#Bean
public OkHttpClient client() {
return new OkHttpClient();
}
}
Explanation: For 401, 407 and some other HTTP-status responses, bodies are replaced with null by HTTP clients used in Open Feign by default.
From OpenFeign: Currently in the feign.Default client there is a streaming mode enabled. You can see in the sun.net.www.protocol.http.HttpURLConnection following lines of code :
if (respCode == HTTP_UNAUTHORIZED) {
if (streaming()) {
disconnectInternal();
throw new HttpRetryException (RETRY_MSG2, HTTP_UNAUTHORIZED);
}
}
So if the streaming is enabled and you have 401 HTTP response code you will get empty errorStream, because there is no initialization. The feign client will try to get the errorStream as a body because there is a check
if (status >= 400) {
stream = connection.getErrorStream();
} else { stream = connection.getInputStream(); }
I have the following ws inbound gateway. How can I do this configuration with Spring Integration Java 8 DSL?
<int-ws:inbound-gateway id="ws-inbound-gateway"
request-channel="ws-request-channel"
reply-channel="ws-response-channel"
error-channel="ws-error-channel"/>
Unfortunally I don't find a first level support for this kind of inbound gateway, however you can fix this as below:
#Configuration
#EnableIntegration
public class IntegrationConfiguration {
#Bean
public SimpleWebServiceInboundGateway SimpleWebServiceInboundGateway() {
SimpleWebServiceInboundGateway simpleWebServiceInboundGateway = new SimpleWebServiceInboundGateway();
// your inbound configurtion
.....
return simpleWebServiceInboundGateway;
}
#Bean
public IntegrationFlow integrationFlow(){
return IntegrationFlows.from(SimpleWebServiceInboundGateway())
// your pipeline
.....
.get();
}
}
in your maven pom don't forget this dependency
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-java-dsl</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ws</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
I hope that this can help you