How To Override Default SQS Configurations For Spring Cloud AWS Messaging - java

Specifically looking to override the default AmazonSQSAsync client in order to ensure that the client is compatible with FIFO queues as mentioned in the version 2.4.2 documentation here . Defining a bean in my application in a #Configuration class similar to the documentation (as shown below) still results in the warning AmazonSQSBufferedAsyncClient that Spring Cloud AWS uses by default to communicate with SQS is not compatible with FIFO queues. Consider registering non-buffered AmazonSQSAsyncClient bean. Although, requests do seem to work I have not yet been able to determine if the correct AmazonSQSAsync client is being used. I'm looking for either a way to adjust my configuration that removes this warning (because my
AmazonSQSAsync bean is being used) or way to confirm that the message is actually a red herring. The dependency I'm using is spring-cloud-aws-messaging version 2.4.2
#Configuration
public class SQSConfig {
#Bean
public AmazonSQSAsync amazonSQS(#Value("${aws.region}") String awsRegion) {
return AmazonSQSAsyncClientBuilder.standard()
.withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
.withRegion(awsRegion)
.build();
}
}

Looks like it was an error with configuration. I had mistakenly left the xml configuration <aws-messaging:annotation-driven-queue-listener /> active which was the source of the erroneous SQS client. Removing that xml configuration and including an override of the amazonSQS bean (bean name must match exactly) with an instance of AmazonSQSAsync solved the issue.

Related

What are the correct Springboot -Kafka parameters in application.yml?

Trying out a hands on with Springboot-Kafka. A couple of doubts. Are these valid parameters for Kafka tuning in application.yml:
fetch-max-bytes: 52428800
Any idea if this is a valid property on Kakfa? I am using it in application.yml in my springboot project to control my consumer polling behaviour. Secondly, in this block are there multiple threads launched internally by the KafkaListener:
#KafkaListener(id = "instance1", groupId = "${spring.kafka.consumer.group-id}", topics = "${spring.kafka.consumer.topic}")
public void consume(String message) {
System.out.println("Hellolistener ..."+message);
log.info("container1 Message recieved from Kafka topic :{} ", message);
}
Thanks in advance.
Without a prefix, those are just regular user-properties that you would need to wire in yourself via #Value
You can find all spring.kafka properties in the Spring documentation
That being said, the two properties you listed are not listed there, but that doesn't prevent you from creating your own ConsumerFactory where those properties could get added
If you are using org.springframework.kafka:spring-kafka, please see the following images, it does not have mentioned properties.
On your other question, for concurrent kafka listeners I created a #Bean of ConcurrentKafkaListenerContainerFactory and pass it as an argument to the parameter containerFactory in #KafkaListener annotation.

JPA outbound channel adapter config in Spring Integration Java DSL

I see there is still no JPA high-level support in Spring Integration Java DSL
Example Spring integration DSL for JPA Inbound Channel adapter
But how it is possible to configure JPA outbound channel adapter on low level?
E.g. to create Java DSL config like this in XML
<int-jpa:outbound-channel-adapter id="moduleMessagePersister" channel="inputPersisterChannel" persist-mode="MERGE" entity-manager-factory="entityManagerFactory">
<int-jpa:transactional transaction-manager="transactionManager"/>
</int-jpa:outbound-channel-adapter>
I remember as promised a contribution :-).
Re. <int-jpa:outbound-channel-adapter>:
Any such an XML component is a Consumer Endpoint for the particular MessageHandler.
See the latest changes in the Core project to help users to determine what to use for the Java & Annotation configuration. And therefore for Java DSL as well: https://jira.spring.io/browse/INT-3964
So, for this particular element we have:
<xsd:documentation>
Configures a Consumer Endpoint for the
'org.springframework.integration.jpa.outbound.JpaOutboundGatewayFactoryBean' (one-way)
updating a database using the Java Persistence API (JPA).
</xsd:documentation>
Therefore we have to configure something like
#Bean
public FactoryBean<MessageHandler> jpaMessageHandler() {
JpaOutboundGatewayFactoryBean factoryBean = new JpaOutboundGatewayFactoryBean();
...
factoryBean.setProducesReply(false);
return factoryBean;
}
And use it from the DSL:
#Bean
public IntegrationFlow jpaFlow(MessageHandler jpaMessageHandler) {
...
.handle(jpaMessageHandler)
.get();
}
Let me know what should be documented else!
And yes: we definitely should utilize JPA adapters in the next 1.2 Java DSL version...

What is the java config equivalent to tcp-outbound-gateway?

I have the following spring-integration XML config
<ip:tcp-outbound-gateway id="outboundClient"
request-channel="requestChannel"
reply-channel="string2ObjectChannel"
connection-factory="clientConnectionFactory"
request-timeout="10000"
reply-timeout="10000"/>
How can I write the Java config equivalent of the above?
I thought the equivalent would be
#Bean
public TcpOutboundGateway outboundClient() {
TcpOutboundGateway tcpOutboundGateway = new TcpOutboundGateway();
tcpOutboundGateway.setConnectionFactory(clientConnectionFactory());
tcpOutboundGateway.setRequiresReply(true);
tcpOutboundGateway.setReplyChannel(string2ObjectChannel());
tcpOutboundGateway.setRequestTimeout(10000);
tcpOutboundGateway.setSendTimeout(10000);
return tcpOutboundGateway;
}
But I couldn't find a way to set the request channel.
Any help would be appreciated.
Thank you
Your config looks good, but you should know in addition that any Spring Integration Consumer component consists of two main objects: MessageHandler (TcpOutboundGateway in your case) and EventDrivenConsumer for subscriable input-channel or PollingConsumer if input-channel is Pollable.
So, since you already have the first, handling, part you need another consuming. For this purpose Spring Integration suggests to mark your #Bean with endpoint annotations:
#Bean
#ServiceActivator(inputChannel = "requestChannel")
public TcpOutboundGateway outboundClient() {
See more in the Spring Integration Reference Manual.
However to allow such a annotation process (or any other Spring Integration infrastructure) you have to mark your #Configuration with #EnableIntegration.
Also consider to use Spring Integration Java DSL to have more gain from JavaConfig.

camel proxy complains about wrong type

I configured a spring boot based application to use remoting with activemq/jms. The listening part is running fine but I have problems implementing the sending part.
For the sender I went back to "classic" camel and spring because I found more working examples for this but still receive an error:
org.springframework.beans.factory.BeanNotOfRequiredTypeException:
Bean named 'myProxy' must be of type [foo.bar.YouNameIt],
but was actually of type [com.sun.proxy.$Proxy83]
This is the way I try to load the proxy definition:
ApplicationContext context = new ClassPathXmlApplicationContext("config/spring.xml");
YouNameIt youNameIt = context.getBean("myProxy", YouNameIt.class);
And this is the entry in the spring.xml:
<camel:proxy id="myProxy"
serviceInterface="foo.bar.IYouNameIt"
serviceUrl="activemq:queue:site12345" />
What am I doing wrong ?
Access the interface IYouNameIt and not the implementation class YouNameIt:
IYouNameIt youNameIt = context.getBean("myProxy", IYouNameIt.class);
See here for a full Spring remoting example.

JMX MXBean Attributes all UNDEFINED - Spring 3.0.x/Tomcat 6.0

I've been trying to get a sample JMX MXBean working in a Spring-configured webapp, but any basic attributes on the MXBean are coming up as UNDEFINED when I connect with jconsole.
Java interface/classes:
public interface IJmxBean { // marker interface for spring config, see below
}
public interface MgmtMXBean { // lexical convention for MXBeans - mgmt interface
public int getAttribute();
}
public class Mgmt implements IJmxBean, MgmtMXBean { // actual JMX bean
private IServiceBean serviceBean; // service bean injected by Spring
private int attribute = 0;
#Override
public int getAttribute() {
if(serviceBean != null) {
attribute = serviceBean.getRequestedAttribute();
}
return attribute;
}
public void setServiceBean(IServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
}
Spring JMX config:
<beans>
<context:component-scan base-package="...">
<context:include-filter type="assignable" expression="...IJmxBean" />
</context:component-scan>
<context:mbean-export />
</beans>
Here's what I know so far:
The element is correctly instantiating a bean named "mgmt". I've got logging in a zero-argument public constructor that indicates it gets constructed.
is correctly automatically detecting and registering the MgmtMXBean interface with my Tomcat 6.0 container. I can connect to the MBeanServer in Tomcat with jconsole and drill down to the Mgmt MXBean.
When examining the MXBean, "Attribute" is always listed as UNDEFINED, but jconsole can tell the correct type of the attribute. Further, hitting "Refresh" in jconsole does not actually invoke the getter method of "Attribute"- I have logging in the getter method to indicate if it is being invoked (similar to the constructor logging that works) and I see nothing in the logs.
At this point I'm not sure what I'm doing wrong. I've tried a number of things, including constructing an explicit Spring MBeanExporter instance and registering the MXBean by hand, but it either results in the MBean/MXBean not getting registered with Tomcat's MBean server or an Attribute value of UNDEFINED.
For various reasons, I'd prefer not to have to use Spring's #ManagedResource/#ManagedAttribute annotations.
Is there something that I'm missing in the Spring docs or MBean/MXBean specs?
ISSUE RESOLVED: Thanks to prompting by Jon Stevens (above), I went back and re-examined my code and Spring configuration files:
Throwing an exception in the getAttribute() method is a sure way to get "Unavailable" to show up as the attribute's value in JConsole. In my case:
The Spring JMX config file I was using was lacking the default-autowire="" attribute on the root <beans> element;
The code presented above checks to see if serviceBean != null. Apparently I write better code on stackoverflow.com than in my test code, since my test code wasn't checking for that. Nor did I have implements InitializingBean or #PostConstruct to check for serviceBean != null like I normally do on almost all the other beans I use;
The code invoking the service bean was before the logging, so I never saw any log messages about getter methods being entered;
JConsole doesn't report when attribute methods throw exceptions;
The NPE did not show up in the Tomcat logs.
Once I resolved the issue with serviceBean == null, everything worked perfectly. Regardless, +1 to Jon for providing a working demo, since there are literally 50 different ways to configure MBeans/MXBeans within Spring.
I've recently built a sample Spring based webapp that very cleanly enables JMX for latest versions of Spring, Hibernate and Ehcache.
It has examples for both EntityManager based access and DAO access (including transactions!). It also shows how to do annotation based injection in order to negate having to use Spring's xml config for beans. There is even a SpringMVC based example servlet using annotations. Basically, this is a Spring based version of a fairly powerful application server running on top of any servlet engine.
It isn't documented yet, but I'll get to that soon. Take a look at the configuration files and source code and it should be pretty clear.
The motivation behind this is that I got tired of all of the crazy blog posts with 50 different ways to set things up and finally made a single simple source that people can work from. It is up on github so feel free to fork the project and do whatever you want with it.
https://github.com/lookfirst/fallback

Categories

Resources