How to accept custom HTTP error codes with the Micronaut client? - http-status-codes

I'm setting up an HTTP client to an external API. That server has unusual status codes in case of errors in the payload sent (310 to 323).
However, Micronaut's HTTP client throws an IllegalArgumentException when trying to parse that response, due to its limited known list of status codes (https://github.com/micronaut-projects/micronaut-core/blob/master/http/src/main/java/io/micronaut/http/HttpStatus.java)
Moreover, when trying to write an async client with the JavaRx library, that error does NOT lead to an error being thrown immediately. It instead hangs for a few seconds and throws an ReadTimeoutException.
I tried Kotlin extensions to extend the HttpStatus enum, but failed. Not sure it is really possible in the way it is used.
Here is the client code:
#Context
#Requires(beans = [FooConfiguration::class])
class FooClient(
#Client("foo") private val httpClient: RxHttpClient,
private val config: FooConfiguration
) {
private val quoteOrderEndpoint = "/api/quote"
private val AUTH_HEADER = "x-foo-bar"
fun quoteOrder(quoteRequest: QuoteOrderRequest): Single<QuoteOrderResponse> {
val body = JsonFormat.printer().print(quoteRequest)
val httpRequest = HttpRequest.POST<Any>(quoteOrderEndpoint, body)
.header(AUTH_HEADER, config.apiKey)
return httpClient.exchange(httpRequest, String::class.java)
.map { response ->
val builder = QuoteOrderResponse.newBuilder()
JsonFormat.parser().merge(response.body(), builder)
builder.build()
}.singleOrError()
}
}
#ConfigurationProperties("${ServiceHttpClientConfiguration.PREFIX}.foo")
class FooConfiguration {
lateinit var apiKey: String
}
and here is the test code:
class FooClientTest {
lateinit var client: FooClient
lateinit var config: FooConfiguration
#BeforeAll
fun setup() {
val rxHttpClient = RxHttpClient.create(URL("https://sandbox.foo.com"))
config = FooConfiguration()
config.apiKey = "***"
client = FooClient(rxHttpClient, config)
}
#Test
fun testQuoteOrder() {
// This payload is incomplete and the API returns a 310 error.
val request = QuoteOrderRequest.newBuilder()
.build()
val response = client.quoteOrder(request).blockingGet()
assertEquals(request.customer.country, response.customer.country)
}
}
Here is the full stack trace:
17:00:41.446 [multithreadEventLoopGroup-1-2] WARN i.n.channel.DefaultChannelPipeline - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.IllegalArgumentException: Invalid HTTP status code: 310
at io.micronaut.http.HttpStatus.valueOf(HttpStatus.java:146)
at io.micronaut.http.client.FullNettyClientHttpResponse.<init>(FullNettyClientHttpResponse.java:82)
at io.micronaut.http.client.DefaultHttpClient$10.channelRead0(DefaultHttpClient.java:1764)
at io.micronaut.http.client.DefaultHttpClient$10.channelRead0(DefaultHttpClient.java:1725)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.micronaut.http.netty.stream.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:185)
at io.micronaut.http.netty.stream.HttpStreamsClientHandler.channelRead(HttpStreamsClientHandler.java:180)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1429)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1199)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1243)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:502)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:441)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:278)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
17:00:41.463 [multithreadEventLoopGroup-1-2] WARN io.sentry.dsn.Dsn - *** Couldn't find a suitable DSN, Sentry operations will do nothing! See documentation: https://docs.sentry.io/clients/java/ ***
17:00:41.470 [multithreadEventLoopGroup-1-2] WARN io.sentry.DefaultSentryClientFactory - No 'stacktrace.app.packages' was configured, this option is highly recommended as it affects stacktrace grouping and display on Sentry. See documentation: https://docs.sentry.io/clients/java/config/#in-application-stack-frames
io.micronaut.http.client.exceptions.ReadTimeoutException: Read Timeout
at io.micronaut.http.client.exceptions.ReadTimeoutException.<clinit>(ReadTimeoutException.java:26)
at io.micronaut.http.client.DefaultHttpClient.lambda$null$28(DefaultHttpClient.java:1071)
at io.reactivex.internal.operators.flowable.FlowableOnErrorNext$OnErrorNextSubscriber.onError(FlowableOnErrorNext.java:103)
at io.reactivex.internal.operators.flowable.FlowableTimeoutTimed$TimeoutSubscriber.onTimeout(FlowableTimeoutTimed.java:139)
at io.reactivex.internal.operators.flowable.FlowableTimeoutTimed$TimeoutTask.run(FlowableTimeoutTimed.java:170)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
So, the questions are:
1) How can I add custom status codes to the HTTP client.
2) How to avoid the request timeout and throw directly.

This is a bug in http-client and there is, apparently, no workaround.
https://github.com/micronaut-projects/micronaut-core/issues/2189

Related

Unable to bind with active directory

I'm new in this domain and trying to bind with active directory using spring ldap client in java. I have already googled this and tried every given solution on internet but it didn't work for me. I'm getting following exception:
021-08-02T14:14:04,377 DEBUG [AbstractContextSource] - Got Ldap context on server [********]
2021-08-02T14:14:04,381 ERROR [UserService] - #### NamingException #### {}
org.springframework.ldap.UncategorizedLdapException: Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C090A71, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v3839�]; remaining name ‘/’
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:228) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:397) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:309) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:642) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:578) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.find(LdapTemplate.java:1840) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.find(LdapTemplate.java:1861) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.findOne(LdapTemplate.java:1869) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.data.ldap.repository.query.AbstractLdapRepositoryQuery.execute(AbstractLdapRepositoryQuery.java:70) ~[spring-data-ldap-2.3.9.RELEASE.jar:2.3.9.RELEASE]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryQueryMethodInvoker$$Lambda$1419/947388427.invoke(Unknown Source) ~[?:?]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.7.jar:5.3.7]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.7.jar:5.3.7]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.7.jar:5.3.7]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.7.jar:5.3.7]
at com.sun.proxy.$Proxy79.findUserByUsername(Unknown Source) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_45]
at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_45]
Dependencies:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId>
<version>${data.ldap.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>${ldap.core.version}</version>
</dependency>
Following is what I've tried:
#Bean
public LdapContextSource contextSource()
{
LOGGER.atDebug().log("using given ldap server config: {}", ldapServerConfig);
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl(ldapServerConfig.getUrl());
contextSource.setBase(ldapServerConfig.getBaseDn());
contextSource.setUserDn(ldapServerConfig.getUsername());
contextSource.setPassword(ldapServerConfig.getPassword());
contextSource.setAnonymousReadOnly(ldapServerConfig.isReadOnlyConnection());
//TODO: To add the support of TLS v1.0/v1.2/v1.3
if (ldapServerConfig.isTlsEnabled())
{
ExternalTlsDirContextAuthenticationStrategy dirContextAuthenticationStrategy = new ExternalTlsDirContextAuthenticationStrategy();
contextSource.setAuthenticationStrategy(dirContextAuthenticationStrategy);
}
return contextSource;
}
#Bean
public LdapTemplate ldapTemplate(ContextSource pooledContextSource, ContextSource contextSource)
{
LOGGER.atInfo().log("connection pooling enabled: {}", ldapServerConfig.isConnectionPooling());
return ldapServerConfig.isConnectionPooling() ? new LdapTemplate(pooledContextSource) : new LdapTemplate(contextSource);
}
private ResponseEntity<ILdapResponse> authenticate(String username)
{
ResponseEntity<ILdapResponse> responseEntity;
ILdapResponse ldapResponse;
try
{
User user = userRepository.findUserByUsername(username);
Furthermore I've tried to connect with the test server and it's working fine and successfully connected. Following are the test server details
ldap.server.url=ldap://ldap.forumsys.com:389/
ldap.server.baseDn=dc=example,dc=com
ldap.server.username=cn=read-only-admin,dc=example,dc=com
ldap.server.password=password
Also I've tried to connect with the ldap console and got the successful PROD environment connection.I don't know what i'm missing in client due to which i'm unable to connect. Please guide me if i'm missing anything. Thanks in advance
ldapsearch -d 3 -x -h <url> -p 389 -D <DN/username> -W -b <base dn> cn

Spring Integration Ftp remoteFileTemplate got stuck on getting file from ftp

When using RemoteFileTemplate to get 20k files from FTP, always 15 or 20 files got stuck and after 10 minutes FTP return error code:
FTP response 421 received. Server closed connection.
Failed to obtain InputStream for remote file /test/test_file_1245:
425
FTP server config:
MaxInstances 2000 (Limits the overall number of connections)
MaxClients 1000 (Limits the number of connections on a
per-server/vhost basis)
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<groupId>rabbitmq.listener</groupId>
<artifactId>listener</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-amqp</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ftp</artifactId>
</dependency>
</dependencies>
</project>
application.properties
spring.rabbitmq.listener.type=direct
spring.rabbitmq.listener.direct.default-requeue-rejected=false
spring.rabbitmq.listener.direct.consumers-per-queue=5
spring.rabbitmq.listener.direct.prefetch=5
DemoConfiguration.java
#Configuration
#Slf4j
#EnableRabbit
public class DemoConfiguration {
#Bean
public DirectMessageListenerContainer container(final DirectRabbitListenerContainerFactory containerFactory) {
final DirectMessageListenerContainer listenerContainer = containerFactory.createListenerContainer();
listenerContainer.setQueueNames("in_queue"); // has 20.000 messages before starting this application
listenerContainer.setListenerId("listener_in_queue");
return listenerContainer;
}
#Bean
public SessionFactory<FTPFile> sessionFactory() {
final DefaultFtpSessionFactory defaultFtpSessionFactory = new DefaultFtpSessionFactory();
defaultFtpSessionFactory.setClientMode(FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE);
defaultFtpSessionFactory.setHost("ftp.test.com");
defaultFtpSessionFactory.setPort(1021);
defaultFtpSessionFactory.setUsername("test");
defaultFtpSessionFactory.setPassword("test");
return new CachingSessionFactory<>(defaultFtpSessionFactory);
}
#Bean
public RemoteFileTemplate<FTPFile> ftpFileRemoteFileTemplate(final SessionFactory<FTPFile> sessionFactory) {
return new RemoteFileTemplate<>(sessionFactory);
}
#Bean
public IntegrationFlow demoFlow(final DirectMessageListenerContainer container, final RemoteFileTemplate<FTPFile> ftpFileRemoteFileTemplate) {
return IntegrationFlows.from(Amqp.inboundAdapter(container))
.handle((payload, headers) -> {
final String file = payload.toString();
ftpFileRemoteFileTemplate.get(file, stream -> {
try {
log.info("{}: {}", file, IOUtils.toString(stream, StandardCharsets.UTF_8).length());
} finally {
stream.close();
}
});
return null;
})
.get();
}
}
log file
2019-01-28 13:37:32.208 WARN 2688 --- [pool-1-thread-14 ] org.springframework.integration.ftp.session.FtpSession : failed to disconnect FTPClient
org.apache.commons.net.ftp.FTPConnectionClosedException: FTP response 421 received. Server closed connection.
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:388)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:300)
at org.apache.commons.net.ftp.FTP.getReply(FTP.java:732)
at org.apache.commons.net.ftp.FTPClient.completePendingCommand(FTPClient.java:1853)
at org.springframework.integration.ftp.session.FtpSession.finalizeRaw(FtpSession.java:108)
at org.springframework.integration.ftp.session.FtpSession.close(FtpSession.java:150)
at org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession.close(CachingSessionFactory.java:208)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:456)
at org.springframework.integration.file.remote.RemoteFileTemplate.get(RemoteFileTemplate.java:393)
at rabbitmq.listener.DemoConfiguration.lambda$demoFlow$1(DemoConfiguration.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.integration.handler.LambdaMessageProcessor.processMessage(LambdaMessageProcessor.java:102)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:93)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:123)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:162)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:453)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:401)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:205)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$600(AmqpInboundChannelAdapter.java:57)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.createAndSend(AmqpInboundChannelAdapter.java:237)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:204)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1514)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1440)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1428)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1423)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1372)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:995)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:955)
at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
2019-01-28 13:37:32.208 WARN 2688 --- [pool-1-thread-14 ] org.springframework.integration.ftp.session.FtpSession : failed to disconnect FTPClient
org.apache.commons.net.ftp.FTPConnectionClosedException: FTP response 421 received. Server closed connection.
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:388)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:300)
at org.apache.commons.net.ftp.FTP.getReply(FTP.java:732)
at org.apache.commons.net.ftp.FTPClient.completePendingCommand(FTPClient.java:1853)
at org.springframework.integration.ftp.session.FtpSession.finalizeRaw(FtpSession.java:108)
at org.springframework.integration.ftp.session.FtpSession.close(FtpSession.java:150)
at org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession.close(CachingSessionFactory.java:208)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:456)
at org.springframework.integration.file.remote.RemoteFileTemplate.get(RemoteFileTemplate.java:393)
at rabbitmq.listener.DemoConfiguration.lambda$demoFlow$1(DemoConfiguration.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.integration.handler.LambdaMessageProcessor.processMessage(LambdaMessageProcessor.java:102)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:93)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:123)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:162)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:453)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:401)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:205)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$600(AmqpInboundChannelAdapter.java:57)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.createAndSend(AmqpInboundChannelAdapter.java:237)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:204)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1514)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1440)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1428)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1423)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1372)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:995)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:955)
at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
2019-01-28 13:37:32.212 WARN 2688 --- [pool-1-thread-14 ] org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1613)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1517)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1440)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1428)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1423)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1372)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:995)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:955)
at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is java.io.IOException: Failed to obtain InputStream for remote file /test/test_file_1245: 425
at org.springframework.integration.handler.LambdaMessageProcessor.processMessage(LambdaMessageProcessor.java:111)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:93)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:123)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:162)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:453)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:401)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:205)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$600(AmqpInboundChannelAdapter.java:57)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.createAndSend(AmqpInboundChannelAdapter.java:237)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:204)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1514)
... 11 common frames omitted
Caused by: org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is java.io.IOException: Failed to obtain InputStream for remote file /test/test_file_1245: 425
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:451)
at org.springframework.integration.file.remote.RemoteFileTemplate.get(RemoteFileTemplate.java:393)
at rabbitmq.listener.DemoConfiguration.lambda$demoFlow$1(DemoConfiguration.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.integration.handler.LambdaMessageProcessor.processMessage(LambdaMessageProcessor.java:102)
... 29 common frames omitted
Caused by: java.io.IOException: Failed to obtain InputStream for remote file /test/test_file_1245: 425
at org.springframework.integration.ftp.session.FtpSession.readRaw(FtpSession.java:98)
at org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession.readRaw(CachingSessionFactory.java:280)
at org.springframework.integration.file.remote.RemoteFileTemplate.lambda$get$4(RemoteFileTemplate.java:396)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:442)
... 36 common frames omitted
2019-01-28 13:37:32.215 ERROR 2688 --- [pool-1-thread-14 ] org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer : Failed to invoke listener
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1613)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1517)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1440)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1428)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1423)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1372)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:995)
at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:955)
at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149)
at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is java.io.IOException: Failed to obtain InputStream for remote file /test/test_file_1245: 425
at org.springframework.integration.handler.LambdaMessageProcessor.processMessage(LambdaMessageProcessor.java:111)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:93)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:123)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:162)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:453)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:401)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:205)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$600(AmqpInboundChannelAdapter.java:57)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.createAndSend(AmqpInboundChannelAdapter.java:237)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:204)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1514)
... 11 common frames omitted
Caused by: org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is java.io.IOException: Failed to obtain InputStream for remote file /test/test_file_1245: 425
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:451)
at org.springframework.integration.file.remote.RemoteFileTemplate.get(RemoteFileTemplate.java:393)
at rabbitmq.listener.DemoConfiguration.lambda$demoFlow$1(DemoConfiguration.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.integration.handler.LambdaMessageProcessor.processMessage(LambdaMessageProcessor.java:102)
... 29 common frames omitted
Caused by: java.io.IOException: Failed to obtain InputStream for remote file /test/test_file_1245: 425
at org.springframework.integration.ftp.session.FtpSession.readRaw(FtpSession.java:98)
at org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession.readRaw(CachingSessionFactory.java:280)
at org.springframework.integration.file.remote.RemoteFileTemplate.lambda$get$4(RemoteFileTemplate.java:396)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:442)
... 36 common frames omitted
-- EDIT
I replaced CachingSessionFactory with DefaultFtpSessionFactory to avoid pool issues and got same behavior. 10 messages were in unacked state on RabbitMQ for 10 minutes. After 10 minutes, I could see that files were processed and there were no more messages on RabbitMQ. I could see that on ftp server one session was in IDLE status for 10 minutes.
#Bean
public SessionFactory<FTPFile> sessionFactory() {
final DefaultFtpSessionFactory defaultFtpSessionFactory = new DefaultFtpSessionFactory();
defaultFtpSessionFactory.setClientMode(FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE);
defaultFtpSessionFactory.setHost("ftp.test.com");
defaultFtpSessionFactory.setPort(1021);
defaultFtpSessionFactory.setUsername("test");
defaultFtpSessionFactory.setPassword("test");
return defaultFtpSessionFactory;
}
This does not seem like pool or FTP 421 problem to me, it is most likely something in the DefaultFtpSessionFactory or session itself? Why are these threads hanging for so long?
The CachingSessionFactory doesn't have a limit by default:
/**
* Create a CachingSessionFactory with the specified session limit. By default, if
* no sessions are available in the cache, and the size limit has been reached,
* calling threads will block until a session is available.
* <p>
* Do not cache a {#link DelegatingSessionFactory}, cache each delegate therein instead.
* #see #setSessionWaitTimeout(long)
* #see #setPoolSize(int)
*
* #param sessionFactory The underlying session factory.
* #param sessionCacheSize The maximum cache size.
*/
public CachingSessionFactory(SessionFactory<F> sessionFactory, int sessionCacheSize) {
and we end up with this configuration in the underlying SimplePool:
/**
* Creates a SimplePool with a specific limit.
* #param poolSize The maximum number of items the pool supports.
* #param callback A {#link PoolItemCallback} implementation called during various
* pool operations.
*/
public SimplePool(int poolSize, PoolItemCallback<T> callback) {
if (poolSize <= 0) {
this.poolSize.set(Integer.MAX_VALUE);
this.targetPoolSize.set(Integer.MAX_VALUE);
this.permits.release(Integer.MAX_VALUE);
}
else {
this.poolSize.set(poolSize);
this.targetPoolSize.set(poolSize);
this.permits.release(poolSize);
}
this.callback = callback;
}
So, consider to have a reasonable cache size for your CachingSessionFactory.

Spring Boot connecting to Pivotal Cloud Cache

My project is using Spring Boot version 2.0.4-RELEASE.
We are deploying onto Pivotal Cloud Foundry and are using the Pivotal Cloud Cache service service which uses Apache Geode.
My code is up and running if I use the gemfire shell to create the Cloud Cache regions but I would like to create these regions from my code instead so that nothing is missed.
I have the following config class where I try to create a region
package com.mycompany.services.config;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.RegionShortcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.EnableCachingDefinedRegions;
import org.springframework.data.gemfire.config.annotation.EnablePdx;
#Configuration
#EnableCachingDefinedRegions
#EnablePdx()
public class Config {
#Bean
public PartitionedRegionFactoryBean<?, ?> createCacheRegion(GemFireCache gemfireCache) {
int expirationTime = 600;
String regionName = "cacheRegion";
PartitionedRegionFactoryBean<?, ?> newRegion = new PartitionedRegionFactoryBean<>();
newRegion.setCache(gemfireCache);
newRegion.setClose(false);
newRegion.setPersistent(true);
newRegion.setName(regionName);
ExpirationAttributes entryTimeToLive = new ExpirationAttributes(expirationTime, ExpirationAction.INVALIDATE);
newRegion.setEntryTimeToLive(entryTimeToLive);
newRegion.setShortcut(RegionShortcut.REPLICATE);
return newRegion;
}
}
However - when this code runs on Pivotal Cloud Foundry - I get the following error
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] 2018-11-08 17:46:09.795 ERROR 19 --- [ main] o.s.boot.SpringApplication : Application run failed
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dqsCacheRegion' defined in class path resource [com/mycompany/services/config/Config.class]: Invocation of init method failed; nested exception is java.lang.UnsupportedOperationException: operation is not supported on a client cache
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:740) ~[spring-beans-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) [spring-boot-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:398) [spring-boot-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.boot.SpringApplication.run(SpringApplication.java:330) [spring-boot-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1258) [spring-boot-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
2018-11-08T17:46:09.797+00:00 [APP/PROC/WEB/0] [OUT] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.4.RELEASE.jar!/:2.0.4.RELEASE]
Can anyone offer any advise on what I need to do in order to create Pivotal Cloud Cache (Apache Geode) regions in my code as opposed to having to create them using the gemfire shell
Thank you
Damien
Client applications can't create regions on the servers, it's a task that should be executed by an operator with admin privileges, either through gfsh, individual cache.xml configuration files or the cluster configuration service. Allowing clients to arbitrarily create regions could be counter-productive and generate a huge amount of unused regions on your cluster and unnecessary noise and overhead, which is not recommended at all for production environments.
That said, Spring Data for Apache Geode/GemFire allows you to push your configuration to the Cluster from a client application automatically, which is useful in developments environments. I don't know if this is allowed by the Pivotal Cloud Cache internal policies and restrictions, you might want to check directly with Pivotal.
Hope this helps.
Cheers.

Spring Boot 2.0.0.M4 throws ConverterNotFoundException on Spring Data REST call

I tried to bump my project up to the most recent Spring Boot 2.0.0 milestone (M4 at the moment of this writing) and I keep getting an exception for a missing Converter (ZonedDateTime to java.util.Date) although it's clearly configured - to me at least. Here's the code and stacktrace:
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import java.time.ZonedDateTime;
import java.util.Date;
#Component
public class ZonedDateTimePersistenceConverter implements Converter<ZonedDateTime, Date> {
#Nullable
#Override
public Date convert(ZonedDateTime source) {
return Date.from(java.time.ZonedDateTime.now().toInstant());
}
}
When calling the respective Spring Data REST endpoint I get:
2017-09-17 21:07:53.634 ERROR 1894 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]] with root cause
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.lambda$getLastModifiedInMilliseconds$5(HttpHeadersPreparer.java:123) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_131]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.getLastModifiedInMilliseconds(HttpHeadersPreparer.java:123) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.prepareHeaders(HttpHeadersPreparer.java:83) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.ResourceStatus.getStatusAndHeaders(ResourceStatus.java:71) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.RepositoryEntityController.lambda$getItemResource$3(RepositoryEntityController.java:337) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_131]
at org.springframework.data.rest.webmvc.RepositoryEntityController.getItemResource(RepositoryEntityController.java:333) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:869) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:775) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:981) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:915) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
...
I've already done some research like debugging and inspecting the GenericConversionService, DefaultConversionService, manually adding it to the converter registry via WebMvcConfigurerAdapter... to no avail.
Any idea where I should look further or what's going here?
Thanks a lot in advance! :)
Edit 1: Additional information to what I've tried and where it's happening. Adding the converter manually didn't help, like so:
#Component
public class AdditionalConverterConfig extends WebMvcConfigurerAdapter {
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new ZonedDateTimePersistenceConverter());
}
}
Funnily, the error occurs when I try to access the URI to one of the entities exposed via a Spring Data REST repository (entity is called "Posting", btw), like so:
#RepositoryRestResource(collectionResourceRel = "postings", path = "postings")
public interface PostingRepository extends PagingAndSortingRepository<Posting, Long> {
}
A GET for /api/postings works just fine, listing the first collection page as expected. GET /api/postings/1 however does not. The only critical ZonedDateTime properties in the entity are from its mapped superclass:
#CreatedDate
protected ZonedDateTime createdAt;
#LastModifiedDate
protected ZonedDateTime modifiedAt;
In the listing they appear just fine - in the detail view... not so much ;)

Netty AsyncRestTemplate Https URL - Connection reset by peer

I'm using `Netty4ClientHttpRequestFactory to configure asyncresttemplate,
public AsyncRestTemplate asyncRestTemplate(Netty4ClientHttpRequestFactory netty4ClientHttpRequestFactory,
#Qualifier("AsyncClientLoggingInterceptor") AsyncClientHttpRequestInterceptor clientHttpRequestInterceptor) {
AsyncRestTemplate restTemplate = new AsyncRestTemplate(netty4ClientHttpRequestFactory);
List<AsyncClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(clientHttpRequestInterceptor);
restTemplate.setInterceptors(Collections.unmodifiableList(interceptors));
return restTemplate;
}
#Bean(name = "netty4ClientHttpRequestFactory")
public Netty4ClientHttpRequestFactory netty4ClientHttpRequestFactory() {
Netty4ClientHttpRequestFactory netty4ClientHttpRequestFactory = new Netty4ClientHttpRequestFactory();
netty4ClientHttpRequestFactory.setConnectTimeout(CONNECT_TIMEOUT);
netty4ClientHttpRequestFactory.setReadTimeout(CONNECT_TIMEOUT);
return netty4ClientHttpRequestFactory;
}
ListenableFuture<ResponseEntity<Void>> future =
asyncRestTemplate.exchange(message.getToUrl(), HttpMethod.POST, httpEntity, Void.class);
Everything works fine with HTTP POST but with Https it throws the following exception,
java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[?:1.8.0_74]
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) ~[?:1.8.0_74]
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[?:1.8.0_74]
at sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[?:1.8.0_74]
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ~[?:1.8.0_74]
at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1100) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:372) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:123) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_74]
On of the reasons for the error message "Connection reset by peer" is, as the client is waiting for a response from the remote service and the connection was closed prematurely.
I configured the Netty4ClientHttpRequestFactory with,
netty4ClientHttpRequestFactory.setSslContext(SslContextBuilder.forClient().build());

Resources