I am trying to inject MessageContext in an Interceptor with the Phase as READ as follows
#Context
org.apache.cxf.jaxrs.ext.MessageContext.MessageContext messageContext;
But this is not getting initialized and remains null. Is it possible to inject org.apache.cxf.jaxrs.ext.MessageContext.MessageContext in Interceptor?
Thanks
You might need to add <aop:scoped-proxy/> into the cxf configuration file:
<jaxrs:server id="example" address="/">
<jaxrs:serviceBeans>
<bean class="org.apache.cxf.systest.jaxrs.CustomerService">
<aop:scoped-proxy />
</bean>
</jaxrs:serviceBeans>
</jaxrs:server>
Also you have to create a setter method for your messageContext (this should be in your service class - here it is "org.apache.cxf.systest.jaxrs.CustomerService"):
private MessageContext messageContext;
#Context
public void setMessageContext(MessageContext messageContext) {
this.messageContext = messageContext;
}
Consider also this documentation link:
http://cxf.apache.org/docs/jaxrs-services-configuration.html#JAXRSServicesConfiguration-FromSpring
Related
We have an issue in the application that the jms message commit on the ibm mq takes hours to complete which inturn causing the log space filling up in ibm mq and also JVM hung issues on the application side. To resolve this, I tried implementing the transaction timeout on the route, jms component etc. But nothing looks to be working.
There are 3 routes in the application
To Read message (Start route)
Deliver/Send message
Error Route (sending to error queue)
The Route definitions are below,
Input/Consumer Route
public class InputRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
from("wmqInConsumer:{{mq.inputQueue}}?concurrentConsumers={{num.consumers}}&maxConcurrentConsumers={{max.num.consumers}}&defaultTaskExecutorType=ThreadPool&preserveMessageQos=true").routeId("input-route").setHeader("Message_Key").method("headerEnricher", "setKey").inOnly("direct:deliver-normal-route-1");
}
}
Deliver Route
public class DeliverRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
from("direct:deliver-normal-route-1").transacted("PROPAGATION_REQUIRES_NEW").inOnly("direct:deliver-route-2");
from("direct:deliver-route-2").process("myServicesProcessor").split()
.method("messageSplitterBean", "splitMessage").shareUnitOfWork().stopOnException()
.toD("wmqDeliverJms:${headers.Deliver}?preserveMessageQos=true");
}
}
Error Route
public class ErrorRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
from("direct:errorChannelRoute").transacted("PROPAGATION_REQUIRES_NEW").inOnly("direct:errorChannelRoute-1");
from("direct:errorChannelRoute-1").process("errorServicesProcessor").split()
.method("messageSplitterBean", "splitErrorMessage").shareUnitOfWork().stopOnException()
.toD("wmqDeliverJms:${headers.Deliver}?preserveMessageQos=true");
}
}
Here the transaction timeouts I tried based on the Camel documentation. But It's not working and I don't see transaction timeout happening in the trace logs too. Also, not sure what will happen to the message if the timeout occurs. Will it go to error queues or full rollback for a retry??
On Input Route, transactionTimeout=10
from("wmqInConsumer:{{mq.inputQueue}}?concurrentConsumers={{num.consumers}}&maxConcurrentConsumers={{max.num.consumers}}&defaultTaskExecutorType=ThreadPool&preserveMessageQos=true&transactionTimeout=10").routeId("input-route").setHeader("Message_Key").method("headerEnricher", "setKey").inOnly("direct:deliver-normal-route-1");
On Input Route JMS Component,
<bean id="wmqInConsumer" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="myConnectionFactory" />
<property name="transacted" value="true" />
<property name="transactionTimeout" value="30"></property> -->
</bean>
On Deliver Route JMS Component,
<bean id="wmqDeliverJms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="myConnectionFactory" />
<property name="destinationResolver" ref="myJmsDestinationResolver" />
<property name="transacted" value="true" />
<property name="transactionTimeout" value="30"></property>
</bean>
I am using properties stored/defined in my blueprint.xml:
<cm:property-placeholder id="props.placeholder" persistent-id="props.blueprint">
<cm:default-properties>
...
<cm:property name="time.daysHistory" value="4" />
</cm:default-properties>
</cm:property-placeholder>
I am using this properties via injection (#PropertyInject) or with this syntax{{time.daysHistory}}.
Is there a way to read and or set those properies from within my Bluprinttests?
I tried context.getProperties() but this returns an empty map.
Like Claus mentioned you need to use the useOverridePropertiesWithConfigAdmin method. However note, you need to return the same pid value as the one configured in your blueprint.
Your blueprint:
<cm:property-placeholder id="props.placeholder" persistent-id="props.blueprint">
<cm:default-properties>
...
<cm:property name="time.daysHistory" value="4" />
</cm:default-properties>
</cm:property-placeholder>
In your test add:
#Override
protected String useOverridePropertiesWithConfigAdmin(Dictionary props) {
props.put("time.daysHistory", "1");
return "props.blueprint";
}
EDIT:
Here is how I have done it:
In my route I have injected properties:
#PropertyInject("DatasetConsumePath")
private String datasetConsumePath;
#PropertyInject("DatasetFileExtension")
private String datasetFileExtension;
My blueprint:
<cm:property-placeholder id="test" persistent-id="test" update-strategy="reload">
<cm:default-properties>
<cm:property name="DatasetConsumePath" value="test"/>
<cm:property name="DatasetFileExtension" value="txt"/>
<cm:property name="DatasetAggregateBatchSize" value="1000"/>
</cm:default-properties>
</cm:property-placeholder>
My test:
#Override
protected String useOverridePropertiesWithConfigAdmin(Dictionary props) {
// add the properties we want to override
props.put("DatasetConsumePath", "src/test/resources/test files/test/");
// return the PID of the config-admin we are using in the blueprint xml file
return "test";
}
See the documentation: http://camel.apache.org/using-propertyplaceholder.html about the loadConfigAdminConfigurationFile and useOverridePropertiesWithConfigAdmin methods you can use from unit tests.
I need to set the use-x-forwarded-headers Http header in camel-cxf like the below and make it as an OSGi bundle to be deployed in Karaf.
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<init-param>
<param-name>use-x-forwarded-headers</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
I don't want to package this as a WAR, instead i want to make it an OSGi bundle.
Hence, i created a class which extends CXFNonSpringServlet as the code below and set the init-params,
public class XForwadedServlet extends CXFNonSpringServlet {
#Override
protected void loadBus(ServletConfig sc) {
sc.getServletContext().setInitParameter("use-x-forwarded-headers",
"true");
super.loadBus(sc);
Bus bus = getBus();
BusFactory.setDefaultBus(bus);
// createFactoryBean();
}
#Override
public void init(ServletConfig sc) throws ServletException {
sc.getServletContext().setInitParameter("use-x-forwarded-headers",
"true");
super.init(sc);
}
And here's my camel route,
<cxf:cxfEndpoint id="serviceEndpoint"
address="http://localhost:8123/cxf/testCxfRedirect"
loggingFeatureEnabled="true" serviceClass="com.redhat.HelloServiceImpl">
</cxf:cxfEndpoint>
<camelContext trace="false" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:serviceEndpoint"/>
<log message="${body}" loggingLevel="INFO"/>
<bean ref="clientAddress" method="getClientAddress"/>
</route>
</camelContext>
<bean id="destinationRegistry" class="org.apache.cxf.transport.http.DestinationRegistryImpl">
</bean>
<bean id="osgiServlet" class="com.redhat.XForwadedServlet">
<constructor-arg ref="destinationRegistry"></constructor-arg>
<constructor-arg value="true"></constructor-arg>
</bean>
Through soapui, i set the X-Forwarded-For header as below,
Address: http://localhost:8123/cxf/testCxfRedirect
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""], X-Forwarded-For=[http://google.com]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHello xmlns:ns1="http://redhat.com/"><arg0 xmlns="http://redhat.com/">Test</arg0></ns1:sayHello></soap:Body></soap:Envelope>
--------------------------------------
How can i register the CXFNonSpringServlet in OSGi Blueprint container with setting that init-params ?
Is there a way to do this in OSGi ?
This can be achieved by using the pax-web-extender support in Fuse, Camel.
However the packaging will need to be WAR.
Here's the reference from Karaf:
https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+War+-+Examples
Here's a reference implementation from the Camel Committers:
https://github.com/apache/camel/tree/master/examples/camel-example-reportincident
Hope it helps.
I am using apache camel to communicate to a remote EJB which is deployed in Weblogic Server 12c. when i invoke remote EJB it throws me the below exception
org.apache.camel.component.bean.MethodNotFoundException: Method with name: sayHi not found on bean: ClusterableRemoteRef(3961905123449960886S:192.168.1.98:[7001,7001,-1,-1,-1,-1,-1]:weblogic:AdminServer [3961905123449960886S:192.168.1.98:[7001,7001,-1,-1,-1,-1,-1]:weblogic:AdminServer/394])/394 of type: com.iexceed.study.HelloRemoteEJBImpl_6zix6y_IHelloRemoteEJBImpl_12120_WLStub. Exchange[Message: [Body is null]]
My Came-context.xml file is as below
<bean id="ejb" class="org.apache.camel.component.ejb.EjbComponent">
<property name="properties" ref="jndiProperties" />
</bean>
<util:properties id="jndiProperties">
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3://IPADDRESS:PORT</prop>
<prop key="java.naming.security.principal">weblogic</prop>
<prop key="java.naming.security.credentials">Weblogic#01</prop>
</util:properties>
<camelContext id="camelclient" xmlns="http://camel.apache.org/schema/spring">
<template id="template" />
<endpoint id="camelejb" uri="ejb:EJBRemoteModule-1_0-SNAPSHOTEJBRemoteModule-1_0-SNAPSHOT_jarHelloRemoteEJBImpl_IHelloRemoteEJB?method=sayHi"/>
<route>
<from uri="direct:start_0" />
<to uri="camelejb" />
</route>
</camelContext>
and the java client class which i am using is
public void postRequest(){
try {
String camelID = "camelejb";
Exchange exchange = null;
Message msg = null;
getCamelContext();
springCamelContext.start();
System.out.println("Starting camel context.....");
getUriMap();
ProducerTemplate template = springCamelContext.createProducerTemplate();
System.out.println("camelejb::::::" + getUriMap().get("camelejb"));
exchange = template.request(getUriMap().get(camelID), new Processor() {
public void process(Exchange exchng) throws Exception {
exchng.getIn().setBody("");
}
});
System.out.println("Exception:" + exchange.getException());
exchange.getException().printStackTrace();
msg = exchange.getOut();
System.out.println("Message:" + msg);
springCamelContext.stop();
System.out.println("Stopping Camel Context....");
} catch (Exception ex) {
ex.printStackTrace();
}
}
EJB :
#Remote
public interface IHelloRemoteEJB {
public void sayHello(String name);
public void sayHi();
}
Having no clue why this error is thrown when the method is available in my EJB.
Will be really grateful from heart because i am already in soup.
What's the result of below code?
getUriMap().get("camelejb")
If you want to reference an endpoint in the camel route, you should do like this
<endpoint id="endpoint1" uri="direct:start"/>
<endpoint id="endpoint2" uri="mock:end"/>
<route>
<from ref="endpoint1"/>
<to uri="ref:endpoint2"/>
</route>
i was creating cxf/camel webservice and i've created for test code like this:
#GET
#Path("/user")
#ProduceMime({ "application/json" })
public String user(#FormParam("token") String token) throws Exception {
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
public void configure(){
from("direct:start").to("http://google.com");
}
});
context.start();
return token;
}
}
Then i've compiled it and copied do FUSE ESB deploy folder. My webservice was installed, but when i opened URL with my webservice i got 500 response:
org.apache.cxf.interceptor.Fault: Failed to create route route17 at: >>> To[http://google.com] <<< in route: Route[[From[direct:start]] -> [To[http://google.com]]] because of Failed to resolve endpoint: http://google.com due to: No component found with scheme: http
Caused by:
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: Failed to create route route17 at: >>> To[http://google.com] <<< in route: Route[[From[direct:start]] -> [To[http://google.com]]] because of Failed to resolve endpoint: http://google.com due to: No component found with scheme: http
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:108)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:323)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:206)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:209)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:152)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:114)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:184)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:112)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:163)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:538)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:478)
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:70)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:480)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:937)
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:116)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:871)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:72)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
at org.eclipse.jetty.server.Server.handle(Server.java:346)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:438)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:905)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:561)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:214)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:43)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:538)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:43)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529)
at java.lang.Thread.run(Thread.java:680)
additionally i have imported:
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.component.http.*;
import org.apache.camel.component.http.helper.*;
on ESB i have turned on camel-http
what is wrong?
--------------
So i this what i wrote is wrong, is this code below should works right?
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/osgi/cxf-extension-osgi.xml" />
<bean id="cxfSSO" class="com.esb.cxf.SSO" />
<jaxrs:server id="sso" address="/ssocamel2">
<jaxrs:serviceBeans>
<ref bean="cxfSSO" />
</jaxrs:serviceBeans>
</jaxrs:server>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<endpoint id="endpointURL" uri="http://localhost:8080/SSO/?token=test"/>
<route>
<from uri="direct:start"/>
<to uri="callRealWebService"/>
</route>
</camelContext>
</beans>
You need to install the camel-http feature. From the Fuse ESB console you can type:
features:install camel-http
And then after that you can install/start your bundle.
And as Ben says, what you are doing inside the rest service is totally wrong. You should setup Camel route once. If you want to call a http endpoint from Java code using Camel, then you do not need a route, but you can use a ProducerTemplate. See the Camel docs for more details.
couple of things, "No component found with scheme: http" means that you are missing the camel-http dependency in your bundle
next, you should setup your Camel context/routes once...not in a method call like this.