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.sql;
12  
13  import jakarta.servlet.http.HttpServletRequest;
14  import jakarta.servlet.http.HttpServletResponse;
15  
16  import java.sql.Connection;
17  import java.sql.DatabaseMetaData;
18  import java.sql.SQLException;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.LinkedHashMap;
22  import java.util.List;
23  import java.util.Map;
24  
25  import javax.naming.NamingException;
26  import javax.sql.DataSource;
27  
28  import org.apache.catalina.Context;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  import org.springframework.beans.factory.annotation.Value;
32  import org.springframework.stereotype.Controller;
33  import org.springframework.web.bind.ServletRequestUtils;
34  import org.springframework.web.bind.annotation.RequestMapping;
35  import org.springframework.web.servlet.ModelAndView;
36  
37  import psiprobe.controllers.AbstractContextHandlerController;
38  
39  /**
40   * Verifies if a database connection can be established through a given datasource. Displays basic
41   * information about the database.
42   */
43  @Controller
44  public class ConnectionTestController extends AbstractContextHandlerController {
45  
46    /** The Constant logger. */
47    private static final Logger logger = LoggerFactory.getLogger(ConnectionTestController.class);
48  
49    @RequestMapping(path = "/sql/connection.ajax")
50    @Override
51    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
52        throws Exception {
53      return super.handleRequest(request, response);
54    }
55  
56    @Override
57    protected ModelAndView handleContext(String contextName, Context context,
58        HttpServletRequest request, HttpServletResponse response) throws Exception {
59  
60      String resourceName = ServletRequestUtils.getStringParameter(request, "resource");
61      DataSource dataSource = null;
62  
63      try {
64        dataSource = getContainerWrapper().getResourceResolver().lookupDataSource(context,
65            resourceName, getContainerWrapper());
66      } catch (NamingException e) {
67        request.setAttribute("errorMessage", getMessageSourceAccessor().getMessage(
68            "probe.src.dataSourceTest.resource.lookup.failure", new Object[] {resourceName}));
69        logger.trace("", e);
70      }
71  
72      if (dataSource == null) {
73        request.setAttribute("errorMessage", getMessageSourceAccessor().getMessage(
74            "probe.src.dataSourceTest.resource.lookup.failure", new Object[] {resourceName}));
75      } else {
76        try {
77          // TODO: use Spring's jdbc template?
78          try (Connection conn = dataSource.getConnection()) {
79            DatabaseMetaData md = conn.getMetaData();
80  
81            List<Map<String, String>> dbMetaData = new ArrayList<>();
82  
83            addDbMetaDataEntry(dbMetaData, "probe.jsp.dataSourceTest.dbMetaData.dbProdName",
84                md.getDatabaseProductName());
85            addDbMetaDataEntry(dbMetaData, "probe.jsp.dataSourceTest.dbMetaData.dbProdVersion",
86                md.getDatabaseProductVersion());
87            addDbMetaDataEntry(dbMetaData, "probe.jsp.dataSourceTest.dbMetaData.jdbcDriverName",
88                md.getDriverName());
89            addDbMetaDataEntry(dbMetaData, "probe.jsp.dataSourceTest.dbMetaData.jdbcDriverVersion",
90                md.getDriverVersion());
91            addDbMetaDataEntry(dbMetaData, "probe.jsp.dataSourceTest.dbMetaData.jdbcVersion",
92                String.valueOf(md.getJDBCMajorVersion()));
93  
94            return new ModelAndView(getViewName(), "dbMetaData", dbMetaData);
95          }
96        } catch (SQLException e) {
97          String message = getMessageSourceAccessor().getMessage(
98              "probe.src.dataSourceTest.connection.failure", new Object[] {e.getMessage()});
99          logger.error(message, e);
100         request.setAttribute("errorMessage", message);
101       }
102     }
103 
104     return new ModelAndView(getViewName());
105   }
106 
107   @Override
108   protected boolean isContextOptional() {
109     return true;
110   }
111 
112   /**
113    * Adds the db meta data entry.
114    *
115    * @param list the list
116    * @param name the name
117    * @param value the value
118    */
119   private void addDbMetaDataEntry(Collection<Map<String, String>> list, String name, String value) {
120     Map<String, String> entry = new LinkedHashMap<>();
121     entry.put("propertyName", getMessageSourceAccessor().getMessage(name));
122     entry.put("propertyValue", value);
123     list.add(entry);
124   }
125 
126   @Value("ajax/sql/connection")
127   @Override
128   public void setViewName(String viewName) {
129     super.setViewName(viewName);
130   }
131 
132 }