Below exception is observed while making a GET call to fetch records from mongo database..
During debuging I saw that if you inspect either one of long totalRecords = mongoTemplate.count(query, searchClass); OR List<V> records = mongoTemplate.find(query.with(page), searchClass); then the first one will pass and the second inspection throws the exception. Whereas in production, the code always fails at the find line as it is the 2nd one to execute. Not sure what is changing in this 10 ns that leads to this exception. To isolate the problem, I was just running one single testcase to avoid any expected data / configuration overlays.
Mongo DB Driver Version : 4.2.3 - 4.6.0 (Reproducible) Spring boot : 2.5.4
Config Code
@TestConfiguration
public class MongoTestConfig {
public static final String DB_NAME = "test";
private static final String CONNECTION_STRING = "mongodb://127.0.0.1:{0}/" + DB_NAME;
private MongodExecutable mongodExecutable;
private MongodProcess mongod;
private Net net;
@PostConstruct
public void startEmbeddedMongoDB() throws IOException {
net = new Net(Network.getFreeServerPort(), Network.localhostIsIPv6());
ImmutableMongodConfig mongodConfig = MongodConfig.builder().version(Version.Main.V5_0).net(net) // mmapv1
.cmdOptions(ImmutableMongoCmdOptions.builder().storageEngine("wiredTiger").build()).build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongodConfig);
mongod = mongodExecutable.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Shutdown Hook is running !");
mongod.stop();
mongodExecutable.stop();
FileUtils.deleteQuietly(PropertyOrPlatformTempDir.defaultInstance().asFile());
}
});
}
@Bean
public Net net() {
return net;
}
@Bean
@Primary
public MongoProperties mongoProperties() {
MongoProperties mongoProperties = new MongoProperties();
mongoProperties.setDatabase(DB_NAME);
mongoProperties.setHost("127.0.0.1");
mongoProperties.setPort(net.getPort());
mongoProperties.setUri(mongoConnectionString(net.getPort()));
mongoProperties.setAutoIndexCreation(true);
return mongoProperties;
}
@Bean
@Primary
public MongoClient mongoClient(Resolvers resolvers, Net net) {
ConnectionString connectionString = new ConnectionString(mongoConnectionString(net.getPort()));
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.applyToConnectionPoolSettings(b ->
b.minSize(2).maxConnectionLifeTime(1, TimeUnit.MINUTES).maxConnectionIdleTime(30, TimeUnit.SECONDS)
)
.applyToSocketSettings(b ->
b.applySettings(SocketSettings.builder().connectTimeout(15, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build()))
.applyToClusterSettings(b -> b.applyConnectionString(connectionString))
.build();
return MongoClients.create(mongoClientSettings);
}
@Bean
@Primary
MongoDatabaseFactorySupport<?> mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties) {
properties.setDatabase(DB_NAME);
properties.setUri(mongoConnectionString(net.getPort()));
return new SimpleMongoClientDatabaseFactory(mongoClient, properties.getMongoClientDatabase());
}
private String mongoConnectionString(int port) {
return MessageFormat.format(CONNECTION_STRING, String.valueOf(port));
}
}
Code to get Records
public Page<V> getAllByTenant(@NotBlank String tenant, Pageable page) {
Class<V> searchClass = getEntityClass();
Query query = Query.query(getTenantCriteria(tenant));
long totalRecords = mongoTemplate.count(query, searchClass);
List<V> records = mongoTemplate.find(query.with(page), searchClass);
return PageableExecutionUtils.getPage(records, page, () -> totalRecords);
}
Exception Trace
org.springframework.data.mongodb.UncategorizedMongoDbException: Interrupted acquiring a permit to retrieve an item from the pool ; nested exception is com.mongodb.MongoInterruptedException: Interrupted acquiring a permit to retrieve an item from the pool
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:140)
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2899)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:555)
at org.springframework.data.mongodb.core.MongoTemplate.doCount(MongoTemplate.java:1130)
at org.springframework.data.mongodb.core.MongoTemplate.count(MongoTemplate.java:1120)
at org.springframework.data.mongodb.core.MongoTemplate.count(MongoTemplate.java:1098)
at com.manish.template.repository.BaseTenantRepositoryImpl.getAllByTenant(BaseTenantRepositoryImpl.java:70)
at com.manish.template.repository.BaseTenantRepositoryImpl$$FastClassBySpringCGLIB$$b957d449.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
at com.manish.registry.repository.DeviceRepositoryImpl$$EnhancerBySpringCGLIB$$20bbaa4e.getAllByTenant(<generated>)
at com.manish.template.web.resource.WebResource.getAll(WebResource.java:163)
at com.manish.registry.web.resource.DeviceResource.getAll(DeviceResource.java:58)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1064)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at com.manish.registry.web.security.SecurityInterceptor.doFilterInternal(SecurityInterceptor.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurer$DelegateFilter.doFilter(SecurityMockMvcConfigurer.java:132)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183)
at io.restassured.module.mockmvc.internal.MockMvcRequestSenderImpl.performRequest(MockMvcRequestSenderImpl.java:199)
at io.restassured.module.mockmvc.internal.MockMvcRequestSenderImpl.sendRequest(MockMvcRequestSenderImpl.java:435)
at io.restassured.module.mockmvc.internal.MockMvcRequestSenderImpl.get(MockMvcRequestSenderImpl.java:476)
at io.restassured.module.mockmvc.internal.MockMvcRequestSenderImpl.get(MockMvcRequestSenderImpl.java:81)
at io.restassured.module.mockmvc.internal.MockMvcRequestSpecificationImpl.get(MockMvcRequestSpecificationImpl.java:582)
at io.restassured.module.mockmvc.internal.MockMvcRequestSpecificationImpl.get(MockMvcRequestSpecificationImpl.java:65)
at com.manish.registry.DeviceInventoryBuildingTest.lambda$0(DeviceInventoryBuildingTest.java:80)
at org.awaitility.core.CallableCondition$ConditionEvaluationWrapper.eval(CallableCondition.java:99)
at org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:222)
at org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:209)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.mongodb.MongoInterruptedException: Interrupted acquiring a permit to retrieve an item from the pool
at com.mongodb.internal.connection.ConcurrentPool.acquirePermit(ConcurrentPool.java:203)
at com.mongodb.internal.connection.ConcurrentPool.get(ConcurrentPool.java:140)
at com.mongodb.internal.connection.ConcurrentPool.get(ConcurrentPool.java:123)
at com.mongodb.internal.session.ServerSessionPool.get(ServerSessionPool.java:80)
at com.mongodb.internal.session.BaseClientSessionImpl.<init>(BaseClientSessionImpl.java:44)
at com.mongodb.client.internal.ClientSessionImpl.<init>(ClientSessionImpl.java:56)
at com.mongodb.client.internal.MongoClientDelegate.createClientSession(MongoClientDelegate.java:102)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.getClientSession(MongoClientDelegate.java:258)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:162)
at com.mongodb.client.internal.MongoCollectionImpl.executeCount(MongoCollectionImpl.java:223)
at com.mongodb.client.internal.MongoCollectionImpl.countDocuments(MongoCollectionImpl.java:192)
at org.springframework.data.mongodb.core.MongoTemplate.lambda$doCount$14(MongoTemplate.java:1131)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:553)
... 87 more
Caused by: java.lang.InterruptedException
at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1343)
at java.base/java.util.concurrent.Semaphore.acquire(Semaphore.java:318)
at com.mongodb.internal.connection.ConcurrentPool.acquirePermit(ConcurrentPool.java:199)
... 99 more
Comment From: snicoll
@DareUrDream Spring Boot 2.5.x is out of OSS support so you'll need to upgrade first and check that it still applies. Please move this to the appropriate issue tracker if you can reproduce with a supported version. And if you do so, please move all the code in text into a sample that the Spring Data team can actually run themselves. Thank you.
Comment From: DareUrDream
Sure will update and check. Thanks !!