View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
10   */
11  package psiprobe.controllers.quickcheck;
12  
13  import jakarta.inject.Inject;
14  import jakarta.servlet.http.HttpServletRequest;
15  import jakarta.servlet.http.HttpServletResponse;
16  
17  import java.io.ByteArrayOutputStream;
18  import java.io.File;
19  import java.io.IOException;
20  import java.io.OutputStream;
21  import java.nio.charset.StandardCharsets;
22  import java.nio.file.Files;
23  import java.nio.file.Path;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.catalina.Context;
28  import org.springframework.web.servlet.ModelAndView;
29  
30  import psiprobe.beans.ContainerListenerBean;
31  import psiprobe.controllers.AbstractTomcatContainerController;
32  import psiprobe.model.ApplicationResource;
33  import psiprobe.model.DataSourceInfo;
34  import psiprobe.model.TomcatTestReport;
35  
36  /**
37   * "Quick check" base controller.
38   */
39  public class BaseTomcatAvailabilityController extends AbstractTomcatContainerController {
40  
41    /** The container listener bean. */
42    @Inject
43    private ContainerListenerBean containerListenerBean;
44  
45    /**
46     * Gets the container listener bean.
47     *
48     * @return the container listener bean
49     */
50    public ContainerListenerBean getContainerListenerBean() {
51      return containerListenerBean;
52    }
53  
54    /**
55     * Sets the container listener bean.
56     *
57     * @param containerListenerBean the new container listener bean
58     */
59    public void setContainerListenerBean(ContainerListenerBean containerListenerBean) {
60      this.containerListenerBean = containerListenerBean;
61    }
62  
63    @Override
64    public ModelAndView handleRequestInternal(HttpServletRequest request,
65        HttpServletResponse response) throws Exception {
66  
67      final long start = System.currentTimeMillis();
68      TomcatTestReport tomcatTestReport = new TomcatTestReport();
69  
70      // check datasource status
71      tomcatTestReport.setDatasourceUsageScore(0);
72  
73      boolean allContextsAvailable = true;
74      if (getContainerWrapper().getResourceResolver().supportsPrivateResources()) {
75        for (Context appContext : getContainerWrapper().getTomcatContainer().findContexts()) {
76          allContextsAvailable = allContextsAvailable
77              && getContainerWrapper().getTomcatContainer().getAvailable(appContext);
78  
79          List<ApplicationResource> applicationResources = getContainerWrapper().getResourceResolver()
80              .getApplicationResources(appContext, getContainerWrapper());
81  
82          for (ApplicationResource appResource : applicationResources) {
83            DataSourceInfo dsi = appResource.getDataSourceInfo();
84            if (dsi != null && dsi.getBusyScore() > tomcatTestReport.getDatasourceUsageScore()) {
85              tomcatTestReport.setContextName(appContext.getName());
86              tomcatTestReport.setDatasourceUsageScore(dsi.getBusyScore());
87              tomcatTestReport.setDataSourceName(appResource.getName());
88            }
89          }
90        }
91  
92        tomcatTestReport.setWebappAvailabilityTest(
93            allContextsAvailable ? TomcatTestReport.TEST_PASSED : TomcatTestReport.TEST_FAILED);
94  
95      } else {
96        List<ApplicationResource> resources =
97            getContainerWrapper().getResourceResolver().getApplicationResources();
98        for (ApplicationResource resource : resources) {
99          DataSourceInfo dsi = resource.getDataSourceInfo();
100         if (dsi != null && dsi.getBusyScore() > tomcatTestReport.getDatasourceUsageScore()) {
101           tomcatTestReport.setDatasourceUsageScore(dsi.getBusyScore());
102           tomcatTestReport.setDataSourceName(resource.getName());
103         }
104       }
105     }
106     tomcatTestReport.setDatasourceTest(TomcatTestReport.TEST_PASSED);
107 
108     // try to allocate some memory
109     String word = "hello";
110     int count = TomcatTestReport.DEFAULT_MEMORY_SIZE / word.length();
111 
112     try {
113       ByteArrayOutputStream bos = new ByteArrayOutputStream();
114       for (; count > 0; count--) {
115         bos.write(word.getBytes(StandardCharsets.UTF_8));
116       }
117       tomcatTestReport.setMemoryTest(TomcatTestReport.TEST_PASSED);
118     } catch (IOException e) {
119       tomcatTestReport.setMemoryTest(TomcatTestReport.TEST_FAILED);
120       logger.trace("", e);
121     }
122 
123     // try to open some files
124     int fileCount = tomcatTestReport.getDefaultFileCount();
125     List<File> files = new ArrayList<>();
126     List<OutputStream> fileStreams = new ArrayList<>();
127 
128     try {
129       for (; fileCount > 0; fileCount--) {
130         File file = Path.of(System.getProperty("java.io.tmpdir"), "tctest_" + fileCount).toFile();
131         try (OutputStream fos = Files.newOutputStream(file.toPath())) {
132           files.add(file);
133           fileStreams.add(fos);
134           fos.write("this is a test".getBytes(StandardCharsets.UTF_8));
135         }
136       }
137       tomcatTestReport.setFileTest(TomcatTestReport.TEST_PASSED);
138     } catch (IOException e) {
139       tomcatTestReport.setFileTest(TomcatTestReport.TEST_FAILED);
140       logger.trace("", e);
141     } finally {
142       for (OutputStream fileStream : fileStreams) {
143         try {
144           fileStream.close();
145         } catch (IOException e) {
146           logger.trace("", e);
147         }
148       }
149       for (File file : files) {
150         Files.delete(file.toPath());
151       }
152     }
153 
154     tomcatTestReport.setTestDuration(System.currentTimeMillis() - start);
155 
156     long maxServiceTime = 0;
157 
158     // TODO JWL 12/11/2016 - Why is this commented out? If not needed, delete it.
159     // check the maximum execution time
160     // List<ThreadPool> pools = containerListenerBean.getThreadPools();
161     // for (int iPool = 0; iPool < pools.size(); iPool++) {
162     // ThreadPool threadPool = (ThreadPool) pools.get(iPool);
163     // List<RequestProcessor> threads = threadPool.getRequestProcessors();
164     // for (int iThread = 0; iThread < threads.size(); iThread++) {
165     // RequestProcessor rp = (RequestProcessor) threads.get(iThread);
166     // if (rp.getStage() == 3) {
167     // // the request processor is in SERVICE state
168     // maxServiceTime = Math.max(maxServiceTime, rp.getProcessingTime());
169     // }
170     // }
171     // }
172 
173     tomcatTestReport.setMaxServiceTime(maxServiceTime);
174 
175     return new ModelAndView(getViewName(), "testReport", tomcatTestReport);
176   }
177 
178 }