Working example on Spring Mediator in WSO2 ESB 4.6.0 - spring

Hi i am working on Spring Mediator in WSO2 ESB 4.6.0, using this and this tutorial
I am getting the Error as follows:
ERROR - SpringMediator Cannot look up Spring configuration conf/sample/resources/spring/springsample.xml
ERROR - SpringMediatorCannot reference application context with key : conf/sample/resources/spring/springsample.xml
Could you please explain me how to solve this.

I got to work this as below,
The class should extends AbstractMediator and override the mediate() method as follows,
package com.test.spring.mediator.workingexampleonspringmediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
public class HelloWorld extends AbstractMediator{
private String message;
public void setMessage(String message){
this.message = message;
}
public boolean mediate(MessageContext arg0) {
System.out.println("HELLO "+message);
return true;
}
}
Then place the jar in [ESBHOME]/repository/components/lib folder
In mediate method it prints a message with the argument like HELLO 'arg'
And I added the following file to registry (/_system/config/repository/spring/springtest.xml),
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="springtest" class="com.test.spring.mediator.workingexampleonspringmediator.HelloWorld" singleton="false">
<property name="message"><value>ISURU</value></property>
</bean>
</beans>
My proxy is as follows,
<proxy xmlns="http://ws.apache.org/ns/synapse" name="testSpring" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<log level="full">
<property name="START" value="__________________________"/>
</log>
<spring:spring xmlns:spring="http://ws.apache.org/ns/synapse" bean="springtest" key="conf:/repository/spring/springtest.xml"/>
<log level="full">
<property name="END" value="______________________"/>
</log>
</inSequence>
</target>
<description></description>
</proxy>
In the proxy you can see the bean=[bean id of the springtest.xml] and class=qualified name of the class
In my ESB terminal, I got the following out put with the given property value in springtest.xml,
[2013-11-07 17:38:30,654] INFO - LogMediator To: /services/testSpring.testSpringHttpSoap12Endpoint, WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:bcae82e9-4027-43c5-bd7a-cbfa885aaf33, Direction: request, START = __________________________, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body/></soapenv:Envelope>
HELLO ISURU
[2013-11-07 17:38:30,692] INFO - LogMediator To: /services/testSpring.testSpringHttpSoap12Endpoint, WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:bcae82e9-4027-43c5-bd7a-cbfa885aaf33, Direction: request, END = ______________________, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body/></soapenv:Envelope>
You must restart the ESB after placing the jar in repository/components/lib

These are the steps for spring mediator in brief as Isuru explained above
Create spring mediator library by extending AbstractMediator
Copy into ESB_HOME/repository/components/lib
Re-start the server
Register springtest.xml file in the Registry
(http://madhukaudantha.blogspot.com/2012/07/wso2-esb-proxy-from-registry.html up to step 5 as Isuru explained)
Then, create a Custom proxy with Spring Mediator.
In there,
add Bean as “springtest” (defined bean id for the mediator class within the xml file)
Select the Key as where the configuration registry file stored according to the 4th step.
Ex : If you have stored that springtest.xml file into path “_system/config/repository/”
Select Key as “/_system/config/repository/springtest.xml”
Note:
Verify in ESB_HOME/repository/components/dropins folder for OSGI
bundle of the mediator of the created spring mediator library which
is copied into ESB_HOME/repository/components/lib. If it is not there
after restarting server, it may be a problem in created mediator
library.
As well as, put unique package name for the mediator class to avoid
conflicts with other mediator class in
ESB_HOME/repository/components/lib.
Keep in mind to add unique bean id for the .xml file which is
registered in the registry when you registered .xml file in 4th step.

This is because of the esb finds the springsample.xml file in the path repository/conf/sample/resources
<parameter name="root">file:repository/conf/sample/resources/</parameter>
But the springsample.xml file location is in repository/samples/resources/ . Therefore it should be corrected as the following,
<parameter name="root">file:repository/samples/resources/</parameter>
In documentation, the configuration is not correct, If you start the esb by the command wso2esb-samples -sn 470 (as mentioned in the documentation) the esb will load the file in repository/samples/synapse_sample_470.xml where in this file above parameter is correctly configured.
Hope this will solve your problem :)
UPDATED:
According to your comment, as your are directly using sample spring example, this occur due to permission of the file trying to access, Or this can be due to file path error. So please try with absolute file url.

when i send a message, the only error message i got is this one
ERROR - SpringMediator No bean named 'springtest' is defined
so it means, the config file has been found. But what about the instanciation of the bean inside, i cannot see any explicit error. The jar file is in components/lib and i can see it also in dropins folder.
:/

Related

How to secure a camel cxf endpoint (https) in FUSE 7.6?

We have been using camel-cxf service endpoints for multiple applications. They works well. Recently we have a need to secure these service endpoints. Therefore, we are adding <httpu:engine-factory> configuration to the camel-context.xml.
We also configured FUSE 7.6 server to have the secure port at 8183 by setting
[FUSE 7.6 Install]/etc/org.ops4j.pax.web.cfg file:
org.osgi.service.http.port = 8181
org.osgi.service.http.port.secure = 8183
org.ops4j.pax.web.config.file = ${karaf.etc}/undertow.xml
org.ops4j.pax.web.session.cookie.httpOnly = false
org.ops4j.pax.web.session.cookie.secure = true
[FUSE 7.6 Install]/etc/undertow.xml is correctly configured to point
to right keystore and truststore, etc.
Following is the camel-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:httpu="http://cxf.apache.org/transports/http-undertow/configuration"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/transports/http-undertow/configuration
http://cxf.apache.org/schemas/configuration/http-undertow.xsd">
<bean class="com.mycom.myapp.CamelRequestProcessor" id="myProcessor"/>
<cxf:cxfEndpoint address="{{MY_HOST}}:8185{{MY_SVC_ADDRESS}}"
bus="auditBus" id="myWebServiceEndpoint"
serviceClass="com.mycom.myapp.MyWebServiceEndpoint" wsdlURL="wsdl/mySvc.wsdl"/>
<httpu:engine-factory bus="cxf">
<httpu:engine port="8185">
<httpu:tlsServerParameters secureSocketProtocol="$(MY_SECURE_SOCKET_PROTOCOL)">
<sec:keyManagers keyPassword="$(MY_KEY_PASSWORD)">
<sec:keyStore file="$(MY_KEYSTORE)" password="$(MY_KEYSTORE_PASSWORD)" type="JKS"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore file="$(MY_TRUSTSTORE)" password="$(MY_TRUSTSTORE_PASSWORD)" type="JKS"/>
</sec:trustManagers>
<sec:clientAuthentication required="true" want="true"/>
</httpu:tlsServerParameters>
</httpu:engine>
</httpu:engine-factory>
<camelContext id="_myCamelContext" useBlueprintPropertyResolver="true" errorHandlerRef="myErrorHandler">
<route id="_firstRuote">
<from id="_from" uri="cxf:bean:myWebServiceEndpoint"/>
<bean id="_processor" method="process" ref="myProcessor"/>
<to id="_to4" uri="direct:otherEndpoints"/>
</route>
</camelContext>
</blueprint>
After we add <httpu:engine-factory/>section, the code is built and deployed to FUSE 7.6. Everything goes well. There is no error in the log, and the bundle starts normally. When I inspected the service at https://myhost:8183/cxf, the service is displayed in browser
Endpoint address: https://my host:8185/cxf/MyWebServiceEndpoint/<br>
WSDL : {namespace}MyWebServiceEndpoint <--This is a link-->
However, when I click the WSDL link, it spins a few seconds, then displays "Unable to connect". It should display the WSDL file.
The browser address bar does point to the correct URL
https://myhost:8185/cxf/MyWebServiceEndpoint/?wsdl
Any help is greatly appreciated.
Your camel-cxf endpoint has
<sec:clientAuthentication required="true" want="true"/>
Which means your client(in this case a browser to load the wsdl) also needs to provide the private key(keystore).
Did you import truststore/keystore that you used for the camel-cxf endpoint into your browser?
The issue is resolved. The undertow configuration has to specify host as the following, which makes the port accessible:
<httpu:engine host="0.0.0.0" port="8185">

The camel message exchange property is not being resolved when used in validator uri component

I am trying to validate the xml file against the xsd using the validator component of camel using blueprint DSL.
<to id="validateXML" uri="validator:file:D:/data/schema/flow.xsd" /> --> working
<to id="validateXML" uri="validator:file:${property.flowXsdPath}" /> --> Not working
flowXsdPath is an exchange property which is set to the xsd location defined by the variable xsdPathVar as given below:
exchange.setProperty("flowXsdPath", exchange.getContext().resolvePropertyPlaceholders(xsdPathVar));
I get exception "Failed to create Producer for endpoint: Endpoint[validator://file:$%7Bproperty.flowXsdPath%7D]. Reason: java.io.FileNotFoundException: ${property.flowXsdPath} (The system cannot find the file specified)"
Though I can access the property value in a log message just before validating the xml file, like this
<log message="File ${file:name} XSD Location = ${property.flowXsdPath}" />
2017-10-16 11:48:44,037 | INFO | processXMLFiles] | file-jms-hums-route | ID-ITEM-XXXXX-49898-1508134722113-0-3 | File 20150603-161237-A412-MFSC.xml XSD Location = D:/data/schema/FSC.xsd
Could you please help how can I access this property inside validator file component?
You should use Dynamic To <toD> instead of <to> to send a message to a dynamic computed Endpoint.
See the related section in http://camel.apache.org/message-endpoint.html

how to setup load-time weaving with Spring and Tomcat WITHOUT using the -javaagent on the command line

I am using Spring 3.2.9, Tomcat 6.0.44
I am trying to configure my application's Spring instrumentation provider (e.g. spring-instrumentation.jar) for load-time weaving, when it is deployed on Tomcat.
I have a requirement to NOT use:
"-javaagent:/path/path/spring-instrument.jar" on the command line to do the configuration.
I've read that I can configure the Spring instrumentation by modifying the <Context> element of my application's Tomcat configuration (in either Tomcat's server.xml or my web app's context.xml). Adding the appropriate <Context> element to the server.xml results in my application being correctly configured to run with Spring's instrumentation provider. Adding it to the context.xml (see below) does NOT result in a working setup.
I have a META-INF/aop.xml file, looks like this:
<aspectj>
<weaver options="-verbose -showWeaveInfo -debug">
<include within="com.mv.xx.services..*"/>
<exclude within="com.mv.xx.aop..*"/>
</weaver>
<aspects>
<aspect name="com.mv.xx.aop.MyAspect"/>
</aspects>
</aspectj>
I also specify that I want to use load-time weaving by adding this to my Spring context config:
<context:load-time-weaver />
And I add this jar to my application's classpath:
spring-instrument-tomcat.jar
WHAT I HAVE TRIED:
When starting Tomcat, If I identify the location of the spring-instrument.jar on the command line using the -javaagent parameter like this:
-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar
Everything works fine.
Next I removed "-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar" from the command line.
In Tomcat's server.xml file (located in $CATALINE_HOME/conf), I added a a <Context> element to the <Host> element, like this:
<Context path="/myApp" docBase="myApp">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
With this configuration everything behaves properly. However I have a requirement to not modify Tomcat's server.xml, since I don't have control over the server.xml (DevOps does, and is reluctant to modify it).
Next I removed the <Context> element from Tomcat's server.xml.
According to the Spring docs, I can add a /META-INF/context.xml to my webapp, and put the <Context> element that used to be in Tomcat's server.xml into the context.xml, like so:
<Context>
<Context path="/myApp" docBase="myApp">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
</Context>
However when I restart Tomcat, I get an error message in the logs saying:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.apache.catalina.loader.WebappClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
After digging around, I read something that suggested that I modify the <context:load-time-weaver/> element in my Spring config, like this:
<context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
And add the jar containing InstrumentationLoadTimeWeaver.class to my classpath.
However when I do that, I get this error message in the logs:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.
etc....
Can anyone explain how to setup load-time weaving with Spring and Tomcat WITHOUT using the -javaagent on the command line, and WITHOUT modifying the server.xml?
This is the code that I managed to use in order to removed the exception that you mentioned.
Basically you have to implement the LoadTimeWeavingConfigurer and override the method getLoadTimeWeaver().
#Configuration
#ComponentScan(basePackages = "org.myproject")
#EnableAspectJAutoProxy
#EnableSpringConfigured
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.AUTODETECT)
public class Config implements LoadTimeWeavingConfigurer {
#Override
public LoadTimeWeaver getLoadTimeWeaver() {
return new ReflectiveLoadTimeWeaver();
}
#Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
return loadTimeWeaver;
}
}
I used invesdwin-instrument to perform that. It allows you to use Load time weaving instrumentation dynamically so that you don't have to use any javaagent.
It took me a bit of effort to make it work with Tomcat 8.5 though. But it finally work using this configuration with Spring Boot :
#SpringBootApplication
#EnableLoadTimeWeaving // instead of #ImportResource(locations = "classpath:/META-INF/ctx.spring.weaving.xml")
public class MySpringBootApplication {
public static void main(final String[] args) {
DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present
DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans
SpringApplication.run(MySpringBootApplication.class, args); //start application, load some classes
}
}
It should also work with previous version of Tomcat.
Regards
https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving
Try maven plug-in from the above link. It's working

Spring XD Java config doesn't load xml resource

I am using Spring XD to create stream twittersearch then wired to my tweet-processor then wired to log.
I used Java config class all fine no issues, then I wanted to add applicationContext.xml in my ModuleConfiguration class using #ImportResource
#Configuration
#ImportResource("config/applicationContext.xml")
#EnableIntegration
public class ModuleConfiguration {
#Bean
MessageChannel input() {
return new DirectChannel();
}
#Bean
MessageChannel output() {
return new DirectChannel();
}
#Autowired
TweetProcessor tweetProcessor;
#Bean
freemarker.template.Configuration configuration() {
return new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_23);
}
}
And the applicationContext.xml content:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:/apps/conf/application.properties</value>
</list>
</property>
</bean>
</beans>
And my stream definition: stream create --name JustCreate --definition "twittersearch --query=Java | tweet-processor | log" --deploy
When the stream deployed I got error:
2015-10-21T11:26:26+0800 1.2.1.RELEASE WARN twitterSource-1-1 twitter.TwitterSearchChannelAdapter - Exception while reading stream.
org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'singlenode:default,admin,singlenode,hsqldbServer:9393.JustCreate.0'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
I have tried also using spring-module.xml approach (not using Java config at all) and that approach works.
But I am just curious whether Spring XD Java config not supporting #ImportResource annotation.
Thanks.
Spring XD creates an application context in the normal normal way from an XML or #Configuration class once it locates and resolves the configuration resources. XD looks in the config directory. If it finds a .xml or or .groovy file, it will use that file to create the application context. If not, it will look for a .properties file and a base_packages property to scan for #Configuration classes. Since you have an XML file in the config directory, the #Configuration is being ignored. To import resources put them in a different path. This can be a sub-directory of config or a different top level directory. This is discussed in detail in the Modules section of the XD reference guide.

CXF request response logging using log4j: debug

I am trying to enable logging for cxf framework in weblogic application server along with log4j.
I have placed cxf.xml in domain home and have modified setdomainenv to add cxf.xml entry -Dcxf.config.file.url=cxf.xml.
I am setting System.setProperty("org.apache.cxf.Logger", "org.apache.cxf.common.logging.Log4jLogger") before making a webservice call and i have tried configuring all 3 types of configuration specified in http://cxf.apache.org/docs/configuration.html. But nothing seems to work.
I even tried creating org.apache.cxf.Logger file containing value org.apache.cxf.common.logging.Log4jLogger.
my log4j.properties
log4j.rootLogger = DEBUG, FILE
log4j.logger.org.apache.cxf=DEBUG
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=<>/logFile.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n
CXF version: 2.7.5
Please suggest if there is change required for me to log both request and response xml?
Make sure your org.apache.cxf.Logger file is under META-INF/cxf. Inspect your war to make sure.
Also, assuming you are defining your services using jaxws, make sure you're defining loggers under the jaxws:inInterceptor and jaxws:outInterceptor
<jaxws:client id="..." serviceClass="..." address="..." >
<jaxws:outInterceptors>
<ref bean="logOut" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="logIn"/>
</jaxws:inInterceptors>
</jaxws:client>
<bean class='org.apache.cxf.interceptor.LoggingInInterceptor' id='logIn'/>
<bean class='org.apache.cxf.interceptor.LoggingOutInterceptor' id='logOut'/>

Resources