I'm using Mule 3.3.CE
I have a Class called SpringObject which implements Callable interface
package com.threads.test;
import org.mule.api.MuleEventContext;
import org.mule.api.lifecycle.Callable;
public class SpringObject implements Callable {
private String someData;
public String getSomeData() {
return someData;
}
public void setSomeData(String someData) {
this.someData = someData;
}
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
System.out.println("CALL SPRING --->>"+someData);
return eventContext.getMessage();
}
}
And my flow is
<http:connector name="httpConnectorEntryPoint" doc:name="HTTP\HTTPS"/>
<spring:beans xmlns="http://www.springframework.org/schema/beans">
<spring:bean id="component" name="component" class="com.threads.test.SpringObject" lazy-init="false">
</spring:bean>
</spring:beans>
<flow name="TestThreadsFlow1" doc:name="TestThreadsFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8099" path="m" connector-ref="httpConnectorEntryPoint" doc:name="HTTP"/>
<set-payload value="#["ExitA"]" doc:name="Set Payload"/>
<component doc:name="Java">
<spring-object bean="component">
<property key="someData" value="Information"/>
</spring-object>
</component>
</flow>
The problem is that when I run my flow and use the http connector, the console shows
CALL SPRING --->>null
instead of
CALL SPRING --->>Information
What could be?
you can try to configure your spring bean outside the flow as follow:
<spring:bean id="component" name="component"
class="com.threads.test.SpringObject" lazy-init="false">
<spring:property name="someData" value="Information" />
</spring:bean>
and inside the flow do:
<component>
<spring-object bean="component" />
</component>
From the property element description in the XSD:
Sets a Mule property. This is a name/value pair that can be set on
components, services, etc., and which provide a generic way of
configuring the system. Typically, you shouldn't need to use a generic
property like this, since almost all functionality is exposed via
dedicated elements. However, it can be useful in configuring obscure
or overlooked options and in configuring transports from the generic
endpoint elements.
This means it's not intended for what you are trying to use it. The appropriate way to set a property in your bean is as follows:
<spring:bean id="component" name="component" class="com.threads.test.SpringObject" lazy-init="false">
<spring:property name="someData" value="Information"/>
</spring:bean>
Related
I have a Java class and a Camel-route configured with XML and am trying to call the getData method from the Camel-route, but the method is not being invoked.
Java class:
class Test {
public String getData(String name) {
return name;
}
}
Camel-route:
<route id="validate" autoStartup="true" streamCache="true">
<setHeader name="data">
<simple>
<method ref="test" method="getData('Test')"/>
</simple>
</setHeader>
</route>
In my camel-context.xml I've created the bean-reference as such:
<bean id="test" class="com.Test" />
This is resolved now.. instead of using method tag use bean tag
<bean ref="test" method="getData" />
I am trying to do the following using spring integration.
I would like to read from an input channel an incoming Message that goes throws a series of Steps and produces a final message.Each step can throw an Exception. This could be either due to a DB call or ExternalCall etc. Each step is considered as a service-activator. If all is well a successful a final Message is generated.I need to handle each Exception thrown by each Step as a separate case and then produce the appropriate final Message.
Using the below xml I have written a test code that passes when sucessfull but when an error occurs although I see a Final message generated in the postSend (sent=true) on channel 'bean 'finalChannel' log but the process does not return to the final queue.
Why does this happen?
<?xml version="1.0" encoding="UTF-8"?>
<context:component-scan base-package="com.demo.">
</context:component-scan>
<header-enricher input-channel="inputChannel"
output-channel="enrichedChannel">
<header name="initialMessage" expression="getPayload()" />
</header-enricher>
<!-- first-step -->
<service-activator input-channel="enrichedChannel"
output-channel="firstStep" ref="validateOne" />
<gateway id="validateOne" default-request-channel="ch1"
error-channel="errors1" />
<chain input-channel="ch1">
<service-activator id="mockServiceOneActivator"
ref="mockServiceOne" method="register" />
</chain>
<!-- enrich-header with payload to be available down the line -->
<header-enricher input-channel="firstStep"
output-channel="secondStep">
<header name="initialInfo" expression="getPayload()" />
</header-enricher>
<!-- second-step -->
<service-activator input-channel="secondStep"
output-channel="enrichWithTwoChannel" ref="validateTwo" />
<gateway id="validateTwo" default-request-channel="ch2"
error-channel="errors2" />
<chain input-channel="ch2">
<service-activator id="mockServiceTwoActivator"
ref="mockServiceTwo" method="callExternal" />
</chain>
<!-- enrich-header with payload to be available down the line -->
<header-enricher input-channel="enrichWithTwoChannel"
output-channel="eligibilityCheck">
<header name="serviceTwoInfo" expression="getPayload()" />
</header-enricher>
<!-- final-step -->
<service-activator input-channel="eligibilityCheck"
output-channel="finalChannel" id="mockServiceFinalActivator"
ref="mockServiceFinal" method="submit" />
<!-- error handling -->
<service-activator input-channel="errors1"
output-channel="finalChannel" ref="traceErrorHandler"
method="handleFailedTrace" />
<service-activator input-channel="errors2"
output-channel="finalChannel" ref="traceErrorHandler2"
method="handleFailedTrace" />
<channel id="finalChannel">
<queue />
</channel>
<service-activator input-channel="errorChannel"
ref="globalExceptionHandler" method="handleError" />
My handler code looks like this ..
#Component("traceErrorHandler")public class TraceErrorHandler {
public Message<FinalMessage> handleFailedTrace(Message<?> errorMessage) {
MessagingException payload = (MessagingException) errorMessage.getPayload();
InitialMessage im = (InitialMessage) payload.getFailedMessage().getHeaders().get("initialMessage");
ServiceOneException error = (ServiceOneException) payload.getCause();
FinalMessage v = new FinalMessage(im.getFrom(), im.getTo(), error.getErrorTemplate());
Message<FinalMessage> finalMessage = MessageBuilder.withPayload(v).copyHeaders(payload.getFailedMessage().getHeaders()).build();
return finalMessage;
}}
I am not sure if this is the correct approach in regards to error-handling. The initial chains are simple activators but further down the line there will be more logic.
Should we I always use chains to handle separate error channels
Even if its a single activator service called.
Only when there are Multiple service-activator/transforms that encapsulate a single point of error?
EDIT 1
I added a request-handler-advice-chain reference a bean.
<int:service-activator
id="serviceOneActivator" input-channel="enrichedChannel"
ref="serviceOne" method="register" output-channel="firstStep">
<int:request-handler-advice-chain>
<ref bean="myclass" />
</int:request-handler-advice-chain></int:service-activator>
The reference bean is at first a default definition in xml
<bean id="myclass"
class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
<property name="failureChannel" ref="finalChannel" />
<property name="onFailureExpression" value="#payload"/>
<property name="returnFailureExpressionResult" value="true" />
</bean>
if I add the <property name="onFailureExpression" value="#payload"/> property it fails with:
Cannot convert value of type 'java.lang.String' to required type 'org.springframework.expression.Expression' for property 'onFailureExpression'
What i would like to do is convert the exception message to a final message object? but all expression i have added seem to fail on load.
A chain with one component makes no sense.
A chain is syntactic sugar only, each component still stands alone at runtime.
If you want to handle errors for individual endpoints, consider using ExpressionEvaluatingRequestHandlerAdvices instead.
See https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/messaging-endpoints.html#message-handler-advice-chain
I created a webservice with apache camel using CXF component as bellow :
blueprint.xml:
<bean class="ngtrend.ws.Testws"/>
<!-- Defined the server endpoint to create the cxf-rs consumer -->
<cxf:rsServer id="rsServer" address="http://localhost:9050/route"
serviceClass="ngtrend.ws.Testws" />
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route id="timerToLog">
<from uri="cxfrs://bean://rsServer"/>
<to uri="bean:ngtrend.ws.HelloBean?method=test(Exchange)"/>
<log message="${body}"/>
</route>
</camelContext>
Testws.java:
public class Testws {
#GET
#Path("/test/{id}")
#Produces("application/xml")
//#Consumes("text/xml")
public Integer getAssets(#PathParam("id") int id){
return null;
}
}
and I would like to secure it forcing the customer to send ( or enter on a dialog box if using a browser) login and password (BASIC Http authentication). How can i make this configuration ?
In CXF framework, restful services authentication can be done by using the following approach:
<cxf:rsServer id="rsServer"
address="http://localhost:9050/route">
<jaxrs:serviceBeans>
<ref bean="serviceBean"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="authenticationHandler"/>
</jaxrs:providers>
</cxf:server>
<bean id="serviceBean" class="ngtrend.ws.Testws"/>
<bean id="authenticationHandler" class="yourpackage.Class" />
Create your own handler for authenticationHandler that will implement import org.apache.cxf.jaxrs.ext.RequestHandler.
Use the authentication strategy needed in this class , for example authenticate against database etc.. This should allow for basic authentication.
You can write a class which implements ContainerRequestFilter. And then set it in the cxf:providers as below:
<bean id="authenticationHandler" class="a class which implements ContainerRequestFilter" />
<cxf:rsServer id="xxxRsServer"
address="/xxxservice" serviceClass="xxx.XXXService"
loggingFeatureEnabled="true" loggingSizeLimit="20">
<cxf:providers>
<ref component-id="authenticationHandler"/>
</cxf:providers>
</cxf:rsServer>
In this way, you could override below method
public void filter(ContainerRequestContext requestContext)
For example, you could make a simple authentication based on requestContext.getHeaderString("UserPassInfo"). If succeed, do nothing, otherwise call requestContext.abortWith(Response.status(401).header("WWW-Authenticate", "Basic").build());
I'd like to publish JMX notifications using Spring 3, but would like to avoid using the NotificationPublisherAware interface, since the code is also used by an application that doesn't use Spring. The bean is exposed using MBeanExporter bean. The alternatives I found require registering the mbeans, which I currently do using Spring configuration, so this is a bad option.
Is there a way to avoid using the NotificationPublisherAware interface but still publish notifications?
You don't have to use any Spring class in code. Example:
Interface:
import javax.management.MXBean;
#MXBean
public interface SecurityEventsManagerMXBean {
...
#AttributeMetaData(value="UserLoginFailures", defaultValue="0", description="Total user login failures")
public int getUserLoginFailureCount() ;
...
}
Bean:
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
public class SecurityEventsManager extends NotificationBroadcasterSupport implements SecurityEventsManagerMXBean {
...
private void notifyUserLoginFailure(...) {
Notification notification = new Notification(...) ;
sendNotification(notification)
userLoginFailureCount++ ;
}
}
Here #AttributeMetaData is a convenient meta annotation that defines descriptor keys:
import javax.management.DescriptorKey;
#Documented
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface AttributeMetaData {
#DescriptorKey("displayName")
String value();
....
}
Edit March 08. Configuration to export above Mbean:
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"
p:locateExistingServerIfPossible="true" />
<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy"
p:attributeSource-ref="jmxAttributeSource" />
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"
p:attributeSource-ref="jmxAttributeSource" />
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="server" ref="mbeanServer"/>
<property name="assembler" ref="assembler"/>
<property name="registrationBehaviorName" value="REGISTRATION_FAIL_ON_EXISTING"/>
<property name="beans">
<map>
<entry>
<key>
<util:constant
static-field="x.y.z.SecurityEventsManager.OBJECT_NAME" />
</key>
<ref bean="securityEventsManager" />
</entry>
</map>
</property>
</bean>
<bean id="securityEventsManager" class="x.y.z.SecurityEventsManager" />
As per Spring docs:
The NotificationPublisher interface and the machinery to get it all working is one of the nicer features of Spring's JMX support. It does however come with the price tag of coupling your classes to both Spring and JMX; as always, the advice here is to be pragmatic... if you need the functionality offered by the NotificationPublisher and you can accept the coupling to both Spring and JMX, then do so.
Ref: http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch24s07.html#jmx-notifications-listeners
Spring seems to resolve and create the autowired objects just fine on boot up. But when I try to access them they come back as null. Anyone have any guesses on what might be going on?
Also XML info is blank as I'm only allowed one hyperlink...
<beans xmlns=""
xmlns:xsi=""
xmlns:p=""
xmlns:mvc=""
xmlns:context=""
xsi:schemaLocation="...only allowed one hyperlink" default-autowire="byName">
<mvc:annotation-driven />
<context:component-scan base-package="com.blah.controller"/>
<context:component-scan base-package="com.blah.*.service"/>
<context:component-scan base-package="com.blah.*.dao"/>
<context:annotation-config />
public class AuthFilter extends UsernamePasswordAuthenticationFilter {
#Autowired
private ProfileService profileService;
//.... Do more stuff below that shows profileService coming back as null.
}
I was able to use a debugger to show that the object was being initialized. I can paste my logs here if you guys want but that's a lot to back edit :).
Adding a bit to this where authfilter is defined:
<b:bean id="authenticationFilter" class="com.blah.auth.AuthFilter">
<b:property name="authenticationManager" ref="authenticationManager" />
<b:property name="filterProcessesUrl" value="/login/validate" />
<b:property name="usernameParameter" value="username" />
<b:property name="passwordParameter" value="password" />
<b:property name="authenticationSuccessHandler" ref="authSuccessHandler" />
<b:property name="authenticationFailureHandler" ref="authFailureHandler" />
</b:bean>
The component scan is in springapp-servlet.xml
I've created a pastebin of the boot logs. No dice with moving the component scan. http://pastebin.com/ttC5MPnQ
see if the there is something suspicious in the logs
it appears to me that AuthFilter is not a spring bean - either map it in the xml config, or annotate it with #Component.
remove default-autowire="byName" if you don't have a compelling reason to have it set so.
make sure you use that filter from within the context, and not instantiating it yourself.
make sure you are not referring to a bean defined in a parent context (for example - a bean defined in applicationContext.xml can't access a bean defined in dispatcher-servlet.xml)
place a component-scan in the applicationContext.xml (not the servlet one). (You can retain the one in the servlet xml but limit it to web packages only)