irods-contrib / metalnx-web

Metalnx Web Application
https://metalnx.github.io/
BSD 3-Clause "New" or "Revised" License
36 stars 36 forks source link

Metalnx 2.5.1 search returns Internal Server Error when combining collections and objects #294

Closed peterverraedt closed 1 year ago

peterverraedt commented 2 years ago

We run iRODS 4.2.10 with a mysql database and Metalnx 2.5.1. The new unified search

Dec 3, 2021 @ 16:59:38.872org.irods.jargon.core.exception.JargonException: java.io.IOException: read length is set to zero
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readHeader(IRODSMidLevelProtocol.java:1393)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readMessage(IRODSMidLevelProtocol.java:1029)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readMessage(IRODSMidLevelProtocol.java:1014)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:427)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:553)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:909)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.ClientServerNegotiationService.notifyServerOfNegotiationFailure(ClientServerNegotiationService.java:257)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.ClientServerNegotiationService.negotiateUsingServerProtocol(ClientServerNegotiationService.java:130)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.ClientServerNegotiationService.negotiate(ClientServerNegotiationService.java:106)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.AuthMechanism.clientServerNegotiation(AuthMechanism.java:158)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.AuthMechanism.clientServerNegotiationHook(AuthMechanism.java:72)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.AuthMechanism.authenticate(AuthMechanism.java:196)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.AbstractIRODSMidLevelProtocolFactory.authenticate(AbstractIRODSMidLevelProtocolFactory.java:212)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.AbstractIRODSMidLevelProtocolFactory.instance(AbstractIRODSMidLevelProtocolFactory.java:95)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSProtocolManager.createNewProtocol(IRODSProtocolManager.java:139)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSSimpleProtocolManager.getIRODSProtocol(IRODSSimpleProtocolManager.java:56)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSSession.connectAndAddToProtocolsMap(IRODSSession.java:487)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.connection.IRODSSession.currentConnection(IRODSSession.java:394)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.pub.IRODSGenericAO.<init>(IRODSGenericAO.java:61)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.pub.IRODSGenQueryExecutorImpl.<init>(IRODSGenQueryExecutorImpl.java:57)
Dec 3, 2021 @ 16:59:38.872  at org.irods.jargon.core.pub.IRODSAccessObjectFactoryImpl.getIRODSGenQueryExecutor(IRODSAccessObjectFactoryImpl.java:281)
Dec 3, 2021 @ 16:59:38.872  at com.emc.metalnx.controller.utils.GenQuerySearchUtil.countObjectsImpl(GenQuerySearchUtil.java:256)
Dec 3, 2021 @ 16:59:38.872  at com.emc.metalnx.controller.utils.GenQuerySearchUtil.countDataObjects(GenQuerySearchUtil.java:170)
Dec 3, 2021 @ 16:59:38.872  at com.emc.metalnx.controller.utils.GenQuerySearchUtil.search(GenQuerySearchUtil.java:149)
Dec 3, 2021 @ 16:59:38.872  at com.emc.metalnx.controller.FilePropertiesController.search(FilePropertiesController.java:138)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
Dec 3, 2021 @ 16:59:38.871  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:667)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
Dec 3, 2021 @ 16:59:38.871  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
Dec 3, 2021 @ 16:59:38.871  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
Dec 3, 2021 @ 16:59:38.871  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
Dec 3, 2021 @ 16:59:38.871  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
Dec 3, 2021 @ 16:59:38.871  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726)
Dec 3, 2021 @ 16:59:38.871  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
Dec 3, 2021 @ 16:59:38.871  at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
Dec 3, 2021 @ 16:59:38.871  at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
Dec 3, 2021 @ 16:59:38.871  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
Dec 3, 2021 @ 16:59:38.870  at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
Dec 3, 2021 @ 16:59:38.870  at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
Dec 3, 2021 @ 16:59:38.870  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
Dec 3, 2021 @ 16:59:38.870  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
Dec 3, 2021 @ 16:59:38.870  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Dec 3, 2021 @ 16:59:38.870  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
Dec 3, 2021 @ 16:59:38.870  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
Dec 3, 2021 @ 16:59:38.870  at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.AuthMechanism.clientServerNegotiation(AuthMechanism.java:158)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.AuthMechanism.clientServerNegotiationHook(AuthMechanism.java:72)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.AuthMechanism.authenticate(AuthMechanism.java:196)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.AbstractIRODSMidLevelProtocolFactory.authenticate(AbstractIRODSMidLevelProtocolFactory.java:212)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.AbstractIRODSMidLevelProtocolFactory.instance(AbstractIRODSMidLevelProtocolFactory.java:95)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.IRODSProtocolManager.createNewProtocol(IRODSProtocolManager.java:139)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.IRODSSimpleProtocolManager.getIRODSProtocol(IRODSSimpleProtocolManager.java:56)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.IRODSSession.connectAndAddToProtocolsMap(IRODSSession.java:487)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.connection.IRODSSession.currentConnection(IRODSSession.java:394)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.pub.IRODSGenericAO.<init>(IRODSGenericAO.java:61)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.pub.IRODSGenQueryExecutorImpl.<init>(IRODSGenQueryExecutorImpl.java:57)
Dec 3, 2021 @ 16:59:38.869  at org.irods.jargon.core.pub.IRODSAccessObjectFactoryImpl.getIRODSGenQueryExecutor(IRODSAccessObjectFactoryImpl.java:281)
Dec 3, 2021 @ 16:59:38.869  at com.emc.metalnx.controller.utils.GenQuerySearchUtil.countObjectsImpl(GenQuerySearchUtil.java:256)
Dec 3, 2021 @ 16:59:38.869  at com.emc.metalnx.controller.utils.GenQuerySearchUtil.countDataObjects(GenQuerySearchUtil.java:170)
Dec 3, 2021 @ 16:59:38.869  at com.emc.metalnx.controller.utils.GenQuerySearchUtil.search(GenQuerySearchUtil.java:149)
Dec 3, 2021 @ 16:59:38.869  at com.emc.metalnx.controller.FilePropertiesController.search(FilePropertiesController.java:138)
Dec 3, 2021 @ 16:59:38.869  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Dec 3, 2021 @ 16:59:38.869  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Dec 3, 2021 @ 16:59:38.869  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Dec 3, 2021 @ 16:59:38.869  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
Dec 3, 2021 @ 16:59:38.869  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
Dec 3, 2021 @ 16:59:38.8682021-12-03 15:59:38 ERROR IRODSMidLevelProtocol:1391 - io exception
Dec 3, 2021 @ 16:59:38.868java.io.IOException: read length is set to zero
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.AbstractConnection.read(AbstractConnection.java:645)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readHeader(IRODSMidLevelProtocol.java:1389)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readMessage(IRODSMidLevelProtocol.java:1029)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.readMessage(IRODSMidLevelProtocol.java:1014)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:427)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:553)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.IRODSMidLevelProtocol.irodsFunction(IRODSMidLevelProtocol.java:909)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.ClientServerNegotiationService.notifyServerOfNegotiationFailure(ClientServerNegotiationService.java:257)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.ClientServerNegotiationService.negotiateUsingServerProtocol(ClientServerNegotiationService.java:130)
Dec 3, 2021 @ 16:59:38.868  at org.irods.jargon.core.connection.ClientServerNegotiationService.negotiate(ClientServerNegotiationService.java:106)
Dec 3, 2021 @ 16:59:38.8672021-12-03 15:59:38 ERROR ClientServerNegotiationService:128 - failure in client server negotiation!...sending error message to the server before throwing the failure exception

This was not tested against postgresql, I cannot exclude the possibility that it is database-related.

Digging into the code shows that if in https://github.com/irods-contrib/metalnx-web/blob/master/src/metalnx-web/src/main/java/com/emc/metalnx/controller/utils/GenQuerySearchUtil.java#L123-L137 the if is forced to be skipped (if (false) { }) the searchs works properly (but does not return collections, of course). Digging further shows that the error is triggered at the second invocation of https://github.com/irods-contrib/metalnx-web/blob/master/src/metalnx-web/src/main/java/com/emc/metalnx/controller/utils/GenQuerySearchUtil.java#L253-L254 or https://github.com/irods-contrib/metalnx-web/blob/master/src/metalnx-web/src/main/java/com/emc/metalnx/controller/utils/GenQuerySearchUtil.java#L203-L204. Probably the session is destroyed a bit too much and cannot be recovered.

The following patch fixes search, but I cannot say I understand why, it just circumvents the problem.

diff --git a/src/metalnx-web/src/main/java/com/emc/metalnx/controller/utils/GenQuerySearchUtil.java b/src/metalnx-web/src/main/java/com/emc/metalnx/controller/utils/GenQuerySearchUtil.java
index 15dd92a4..ed87a3ac 100644
--- a/src/metalnx-web/src/main/java/com/emc/metalnx/controller/utils/GenQuerySearchUtil.java
+++ b/src/metalnx-web/src/main/java/com/emc/metalnx/controller/utils/GenQuerySearchUtil.java
@@ -120,14 +120,18 @@ public class GenQuerySearchUtil
         SearchInput searchInput = new SearchInput(_input);
         SearchOutput output = null;

+        IRODSFileSystem fsys = IRODSFileSystem.instance();
+        IRODSAccessObjectFactory factory = fsys.getIRODSAccessObjectFactory();
+        IRODSGenQueryExecutor executor = factory.getIRODSGenQueryExecutor(_input.account);
+
         if (areColumnsSupportedByCollections(searchInput)) {
-            output = findCollections(searchInput);
+            output = findCollections(executor, searchInput);

             if (output.matches > 0) {
                 searchInput.count -= Math.min(output.matches, output.objects.size());
             }
             else {
-                output.matches = countCollections(searchInput);
+                output.matches = countCollections(executor, searchInput);
             }
         }
         else {
@@ -141,42 +145,45 @@ public class GenQuerySearchUtil
         // Look for data objects matching the search criteria if there are empty
         // slots available.
         if (searchInput.count > 0) {
-            SearchOutput dataObjectSearchOutput = findDataObjects(searchInput);
+            SearchOutput dataObjectSearchOutput = findDataObjects(executor, searchInput);
             output.objects.addAll(dataObjectSearchOutput.objects);
             output.matches += dataObjectSearchOutput.matches;
         }
         else {
-            output.matches += countDataObjects(searchInput);
+            output.matches += countDataObjects(executor, searchInput);
         }

+        factory.closeSessionAndEatExceptions();
+        fsys.closeAndEatExceptions();
+        
         return output;
     }

-    public static SearchOutput findDataObjects(SearchInput _input)
+    public static SearchOutput findDataObjects(IRODSGenQueryExecutor executor, SearchInput _input)
         throws GenQueryBuilderException, JargonException, JargonQueryException, ParseException
     {
-        return findObjectsImpl(_input, false /* isCollection */);
+        return findObjectsImpl(executor, _input, false /* isCollection */);
     }

-    public static SearchOutput findCollections(SearchInput _input)
+    public static SearchOutput findCollections(IRODSGenQueryExecutor executor, SearchInput _input)
         throws GenQueryBuilderException, JargonException, JargonQueryException, ParseException
     {
-        return findObjectsImpl(_input, true /* isCollection */);
+        return findObjectsImpl(executor, _input, true /* isCollection */);
     }

-    public static int countDataObjects(SearchInput _input)
+    public static int countDataObjects(IRODSGenQueryExecutor executor, SearchInput _input)
         throws GenQueryBuilderException, JargonException, JargonQueryException, ParseException
     {
-        return countObjectsImpl(_input, RodsGenQueryEnum.COL_DATA_NAME, false /* isCollection */);
+        return countObjectsImpl(executor, _input, RodsGenQueryEnum.COL_DATA_NAME, false /* isCollection */);
     }

-    public static int countCollections(SearchInput _input)
+    public static int countCollections(IRODSGenQueryExecutor executor, SearchInput _input)
         throws GenQueryBuilderException, JargonException, JargonQueryException, ParseException
     {
-        return countObjectsImpl(_input, RodsGenQueryEnum.COL_COLL_NAME, true /* isCollection */);
+        return countObjectsImpl(executor, _input, RodsGenQueryEnum.COL_COLL_NAME, true /* isCollection */);
     }

-    private static SearchOutput findObjectsImpl(SearchInput _input, boolean _isCollection)
+    private static SearchOutput findObjectsImpl(IRODSGenQueryExecutor executor, SearchInput _input, boolean _isCollection)
         throws GenQueryBuilderException, JargonException, JargonQueryException, ParseException
     {
         final boolean distinct = true;
@@ -200,10 +207,7 @@ public class GenQuerySearchUtil

         addQueryConditions(gqlBuilder, _input, _isCollection);

-        IRODSFileSystem fsys = IRODSFileSystem.instance();
-        IRODSAccessObjectFactory factory = fsys.getIRODSAccessObjectFactory();
         IRODSGenQueryFromBuilder gql = gqlBuilder.exportIRODSQueryFromBuilder(_input.count);
-        IRODSGenQueryExecutor executor = factory.getIRODSGenQueryExecutor(_input.account);
         IRODSQueryResultSet resultSet = executor.executeIRODSQueryAndCloseResult(gql, _input.offset);

         List<DataGridCollectionAndDataObject> objects = new ArrayList<>();
@@ -219,9 +223,6 @@ public class GenQuerySearchUtil
             }
         }

-        factory.closeSessionAndEatExceptions();
-        fsys.closeAndEatExceptions();
-
         SearchOutput output = new SearchOutput();

         output.objects = objects;
@@ -230,7 +231,7 @@ public class GenQuerySearchUtil
         return output;
     }

-    private static int countObjectsImpl(SearchInput _input, RodsGenQueryEnum _columnToCount, boolean _isCollection)
+    private static int countObjectsImpl(IRODSGenQueryExecutor executor, SearchInput _input, RodsGenQueryEnum _columnToCount, boolean _isCollection)
         throws GenQueryBuilderException, JargonException, JargonQueryException, ParseException
     {
         final boolean distinct = true;
@@ -250,19 +251,13 @@ public class GenQuerySearchUtil

         addQueryConditions(gqlBuilder, _input, _isCollection);

-        IRODSFileSystem fsys = IRODSFileSystem.instance();
-        IRODSAccessObjectFactory factory = fsys.getIRODSAccessObjectFactory();
         IRODSGenQueryFromBuilder gql = gqlBuilder.exportIRODSQueryFromBuilder(1 /* rows to return */);
-        IRODSGenQueryExecutor executor = factory.getIRODSGenQueryExecutor(_input.account);
         IRODSQueryResultSet resultSet = executor.executeIRODSQueryAndCloseResult(gql, 0 /* offset */);

         final int count = _isCollection
             ? resultSet.getFirstResult().getColumnAsIntOrZero(_columnToCount.getName())
             : resultSet.getTotalRecords();

-        factory.closeSessionAndEatExceptions();
-        fsys.closeAndEatExceptions();
-
         return count;
     }
korydraughn commented 2 years ago

I remember running into weird things when implementing this. I had to create a new filesystem instance and I never figured out why.

Perhaps your changes resolve that?

If you haven't already, please create a PR for this change and we'll look into testing it against Postgres and MySQL.

Also, which search fields did you use to trigger this error?

Have you seen this error on 4.2.11 or 4.3.0 (now that they are available)?

korydraughn commented 2 years ago

@peterverraedt Can you provide input that triggers this?

I have not been able to reproduce this using iRODS 4.2.10 and MySQL 5.7 or PostgreSQL.

peterverraedt commented 2 years ago

I can still reproduce it with the jargon release 4.3.2.5-RELEASE and metalnx version 2.6.0.

Search field: e.g. owner name only.

The patch based above still works, but I still don't exactly know why, that is why it didn't make into a PR.

korydraughn commented 2 years ago

So even after bumping the jargon version and recompiling Metalnx, the problem still exists.

I'm going to give it a try and see what happens.

korydraughn commented 2 years ago

I just tried this against iRODS 4.2.10 and MySQL 5.7. I can't trigger the issue.

Thinking about this more, I feel this is more of a jargon issue. Perhaps I can trigger it outside of Metalnx.

In the meantime, if you can provide any additional information about your setup, that would be helpful.

korydraughn commented 2 years ago

I could not reproduce the issue outside of metalnx with jargon 4.3.2.4-RELEASE either.

Have you reviewed the log files for the MySQL database and the iRODS server when this happens? Do they contain anything of interest?

peterverraedt commented 2 years ago

I checked the logfiles and was able to spot the real issue (or get closer to it). I'm sure I checked those logs earlier but must have missed it then, or logging did improve in the latest release.

The metalnx log metalnx.log shows

[2022-09-09T10:18:41.750Z][icts-t-cloud-hev-1] 2022-09-09 10:18:41 ERROR ClientServerNegotiationService:128 - failure in client server negotiation!...sending error message to the server before throwing the failure exception
[2022-09-09T10:18:41.751Z][icts-t-cloud-hev-1] 2022-09-09 10:18:41 ERROR AbstractConnection:644 - read length is set to zero
[2022-09-09T10:18:41.752Z][icts-t-cloud-hev-1]  at org.irods.jargon.core.pub.IRODSGenericAO.<init>(IRODSGenericAO.java:61)

during the second time

IRODSFileSystem fsys = IRODSFileSystem.instance();
IRODSAccessObjectFactory factory = fsys.getIRODSAccessObjectFactory();
IRODSGenQueryExecutor executor = factory.getIRODSGenQueryExecutor(_input.account);

are called.

We run a custom proxy before irods, that basically inspect the first couple of messages to determine to which backend the connection should be relayed (checking zone and SNI hostname). It shows in proxy.log two connections from metalnx towards irods port 1247:

The first connection is handled well, the second sees cs_neg_result_kw=CS_NEG_FAILURE; from the client at which point the connection is broken.

The proxy always sends

message.IRODSMessageCSNegotiation{
        Status: 1,
        Result: "CS_NEG_REQUIRE",
}

towards the client. Can you check whether the problem can be reproduced if irods itself always returns CS_NEG_REQUIRE?

korydraughn commented 2 years ago

Before I try to reproduce this, I'd like to know if you've tried the following.

Q. If you removed the proxy, does the behavior change? Q. If you disabled SSL, does the behavior change?

Seems the only differences between our deployments is SSL and a proxy.

peterverraedt commented 2 years ago

A: Yes, without the proxy it works as intended. A: I cannot disable SSL because my proxy relies on it, but I discovered the following.

With my proxy, the behaviour of a connection is as follows (and in second connection, the third message below is a failure from the client):

C>S:
<MsgHeader_PI>
<type>RODS_CONNECT</type>
<msgLen>360</msgLen>
<errorLen>0</errorLen>
<bsLen>0</bsLen>
<intInfo>0</intInfo>
</MsgHeader_PI>
<StartupPack_PI>
<irodsProt>0</irodsProt>
<reconnFlag>0</reconnFlag>
<connectCnt>0</connectCnt>
<proxyUser>rods</proxyUser>
<proxyRcatZone>zone</proxyRcatZone>
<clientUser>rods</clientUser>
<clientRcatZone>zone</clientRcatZone>
<relVersion>rods4.3.0</relVersion>
<apiVersion>d</apiVersion>
<option>request_server_negotiation</option>
</StartupPack_PI>

S>C:
<MsgHeader_PI>
<type>RODS_CS_NEG_T</type>
<msgLen>78</msgLen>
<errorLen>0</errorLen>
<bsLen>0</bsLen>
<intInfo>0</intInfo>
</MsgHeader_PI>
<CS_NEG_PI>
<status>1</status>
<result>CS_NEG_REQUIRE</result>              
</CS_NEG_PI>

C>S:
<MsgHeader_PI>
<type>RODS_CS_NEG_T</type>
<msgLen>141</msgLen>
<errorLen>0</errorLen>
<bsLen>0</bsLen>
<intInfo>0</intInfo>
</MsgHeader_PI>
<CS_NEG_PI>
<status>1</status>
<result>cs_neg_sid_kw=someid;cs_neg_result_kw=CS_NEG_USE_SSL;</result>
</CS_NEG_PI>

If I modify my proxy to not send CS_NEG_REQUIRE but CS_NEG_DONT_CARE to the client, and just hope that the client will enable use of SSL (because I need it in my proxy to do SNI), it works well.

I was unable to test this without the proxy, because my irods server seems to send CS_NEG_DONT_CARE even if I require the use of ssl in /var/lib/irods/.irods/irods_environment.json.

I am now wondering whether this is a bug or expected behaviour.

trel commented 2 years ago

my irods server seems to send CS_NEG_DONT_CARE

the server setting is in core.re, please confirm it is what you want it to be...

peterverraedt commented 2 years ago

Ok, thanks, forgot to look there.

I can now confirm that the bug is also present without a proxy if CS_NEG_REQUIRE is set in core.re. That should allow for easy reproduction.

korydraughn commented 2 years ago

So the error appears when there is no proxy, but SSL is required by the server.

You mentioned in this comment, https://github.com/irods-contrib/metalnx-web/issues/294#issuecomment-1243892373, that things worked as intended when the proxy was removed. What was the state of core.re/acPreConnect during that run?

peterverraedt commented 2 years ago

Then core.re defaulted to CS_NEG_DONT_CARE. From tcpdump/ssldump it is seen that also in this case, metalnx connects using ssl in both connections to irods.

korydraughn commented 2 years ago

Got it. Something isn't quite right when the server is configured to require SSL.

We'll look into it.

JustinKyleJames commented 1 year ago

I feel like I have reproduced this error but my stack trace is not identical to the one above.

I enabled SSL. First did a search on data object name. All went well. The correct entries were returned and no errors appeard in the log.

I then did a search on owner name (which should return both data objects and collections) and the server responded with a 500 error. This is the top of the stack trace I got:

2023-01-24 15:55:32 ERROR FilePropertiesController:151 - Could not search by metadata:                                       
org.irods.jargon.core.exception.ClientServerNegotiationException: failure in client server negotiation                                         
        at org.irods.jargon.core.connection.ClientServerNegotiationService.negotiateUsingServerProtocol(ClientServerNegotiationService.java:131)                                                                                                                                               
        at org.irods.jargon.core.connection.ClientServerNegotiationService.negotiate(ClientServerNegotiationService.java:106)   
        at org.irods.jargon.core.connection.AuthMechanism.clientServerNegotiation(AuthMechanism.java:158)    

The proxy might change the specific error.

JustinKyleJames commented 1 year ago

I haven't tracked down the root cause of this but I have confirmed a couple of things.

  1. The code change from above does fix (or hide) the issue.
  2. If you simply remove the session closing logic, the issue does not occur.

This leads me to believe that when you close the sessions and then open them back up, something dealing with SSL is not being set up properly.