openkm / document-management-system

OpenKM is a Open Source Document Management System
https://www.openkm.com/
GNU General Public License v2.0
700 stars 303 forks source link

OpenKM will be crashed when calling the WebService API with a not existing File Path in a loop. #318

Open zengsentry opened 2 years ago

zengsentry commented 2 years ago

OpenKM will be crashed when calling the WebService API with a not existing File Path.

image

It's easy to reproduce, please follow the below steps.

Step1: Using the Java SDK sdk4j.jar in Clinet Application Step2: Write a simple code to call WebService API in a loop.

`
OKMWebservices ws= OKMWebservicesFactory.newInstance(host, user, password);

for (int i = 0; i < 10; i++) { 
    long currentTinme = System.currentTimeMillis()
    try {
        System.out.println("----loop i----  " + I); 
       // this file is not exist,
        Document document = ws.getDocumentProperties("/okm:root/Repository/Test/Readme.txt");
    } catch (RepositoryException e) {
        e.printStackTrace();
    } catch (PathNotFoundException e) {
        e.printStackTrace();
    } catch (DatabaseException e) {
        e.printStackTrace();
    } catch (UnknowException e) {
        e.printStackTrace();
    } catch (WebserviceException e) {
        e.printStackTrace();
    }
    long finishedtTinme = System.currentTimeMillis();
    System.out.println("---Execution time----" + (finishedtTinme - currentTinme));
 }`

Step 3: the bug has reproduced - Client crash log.
image

Step 4: the bug has reproduced - Host crash log.

2022-03-24 09:17:48,322 [http-nio-0.0.0.0-8080-exec-3] WARN o.a.c.j.i.WebApplicationExceptionMapper - com.openkm.rest.GenericException: HTTP 500 Internal Server Error at com.openkm.rest.endpoint.DocumentService.getProperties(DocumentService.java:149) at sun.reflect.GeneratedMethodAccessor707.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:193) at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:103) at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:216) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:225) at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:685) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) Caused by: com.openkm.core.PathNotFoundException: /okm:root/Repository/Test/Readme.txt at com.openkm.dao.NodeBaseDAO.calculateUuidFromPath(NodeBaseDAO.java:242) at com.openkm.dao.NodeBaseDAO.calculateUuidFromPath(NodeBaseDAO.java:212) at com.openkm.dao.NodeBaseDAO.getUuidFromPath(NodeBaseDAO.java:102) at com.openkm.module.db.DbDocumentModule.getProperties(DbDocumentModule.java:417) at com.openkm.rest.endpoint.DocumentService.getProperties(DocumentService.java:145) ... 66 more

darkman97i commented 2 years ago

After the crash the application is still alive or not? Do you have an hprof file in the tomcat folder?

zengsentry commented 2 years ago

After the crash, the application is still alive, if stop the loop call, the web portal will work fine again.

zengsentry commented 2 years ago

hprof file not found in the tomcat folder

darkman97i commented 2 years ago

I think are saturating the application. I think will happen in the same manner if you are doing a right action than an action that cause exception. For example try with a loop that create 5K folder -> if between each request do not apply a delay you are saturating the application it is something like creating a loop in the application what consumes everything.

Please try with create folder and tell me if happens similar issue.

Take a look at the cpu's usage, IO, etc.... Tools like Glowroot can help on capturing snapshot of the virtual machine and watch how resources are consumed -> https://glowroot.org/