Support more lenient DB2 product lookups
Update DataSourceHealthIndicator to support pattern based matching for DB2 products. Prior to this commit product identifiers of the form `DB2/LINUXX8664` were not supported. Fixes gh-3377
This commit is contained in:
		
							parent
							
								
									85535f0882
								
							
						
					
					
						commit
						7dcb79b3b3
					
				| 
						 | 
					@ -20,10 +20,7 @@ import java.sql.Connection;
 | 
				
			||||||
import java.sql.ResultSet;
 | 
					import java.sql.ResultSet;
 | 
				
			||||||
import java.sql.ResultSetMetaData;
 | 
					import java.sql.ResultSetMetaData;
 | 
				
			||||||
import java.sql.SQLException;
 | 
					import java.sql.SQLException;
 | 
				
			||||||
import java.util.Collections;
 | 
					 | 
				
			||||||
import java.util.HashMap;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Map;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.sql.DataSource;
 | 
					import javax.sql.DataSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,18 +48,6 @@ import org.springframework.util.StringUtils;
 | 
				
			||||||
public class DataSourceHealthIndicator extends AbstractHealthIndicator implements
 | 
					public class DataSourceHealthIndicator extends AbstractHealthIndicator implements
 | 
				
			||||||
		InitializingBean {
 | 
							InitializingBean {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final Map<String, String> PRODUCT_SPECIFIC_QUERIES;
 | 
					 | 
				
			||||||
	static {
 | 
					 | 
				
			||||||
		Map<String, String> queries = new HashMap<String, String>();
 | 
					 | 
				
			||||||
		queries.put("HSQL Database Engine", "SELECT COUNT(*) FROM "
 | 
					 | 
				
			||||||
				+ "INFORMATION_SCHEMA.SYSTEM_USERS");
 | 
					 | 
				
			||||||
		queries.put("Oracle", "SELECT 'Hello' from DUAL");
 | 
					 | 
				
			||||||
		queries.put("Apache Derby", "SELECT 1 FROM SYSIBM.SYSDUMMY1");
 | 
					 | 
				
			||||||
		queries.put("DB2", "SELECT 1 FROM SYSIBM.SYSDUMMY1");
 | 
					 | 
				
			||||||
		queries.put("Informix Dynamic Server", "select count(*) from systables");
 | 
					 | 
				
			||||||
		PRODUCT_SPECIFIC_QUERIES = Collections.unmodifiableMap(queries);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private static final String DEFAULT_QUERY = "SELECT 1";
 | 
						private static final String DEFAULT_QUERY = "SELECT 1";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private DataSource dataSource;
 | 
						private DataSource dataSource;
 | 
				
			||||||
| 
						 | 
					@ -145,7 +130,10 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator implement
 | 
				
			||||||
	protected String getValidationQuery(String product) {
 | 
						protected String getValidationQuery(String product) {
 | 
				
			||||||
		String query = this.query;
 | 
							String query = this.query;
 | 
				
			||||||
		if (!StringUtils.hasText(query)) {
 | 
							if (!StringUtils.hasText(query)) {
 | 
				
			||||||
			query = PRODUCT_SPECIFIC_QUERIES.get(product);
 | 
								Product specific = Product.forProduct(product);
 | 
				
			||||||
 | 
								if (specific != null) {
 | 
				
			||||||
 | 
									query = specific.getQuery();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!StringUtils.hasText(query)) {
 | 
							if (!StringUtils.hasText(query)) {
 | 
				
			||||||
			query = DEFAULT_QUERY;
 | 
								query = DEFAULT_QUERY;
 | 
				
			||||||
| 
						 | 
					@ -196,4 +184,53 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator implement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected static enum Product {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							HSQLDB("HSQL Database Engine",
 | 
				
			||||||
 | 
									"SELECT COUNT(*) FROM INFORMATION_SCHEMA.SYSTEM_USERS"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ORACLE("Oracle", "SELECT 'Hello' from DUAL"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DERBY("Apache Derby", "SELECT 1 FROM SYSIBM.SYSDUMMY1"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DB2("DB2", "SELECT 1 FROM SYSIBM.SYSDUMMY1") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								@Override
 | 
				
			||||||
 | 
								protected boolean matchesProduct(String product) {
 | 
				
			||||||
 | 
									return super.matchesProduct(product)
 | 
				
			||||||
 | 
											|| product.toLowerCase().startsWith("db2/");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							INFORMIX("Informix Dynamic Server", "select count(*) from systables");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private final String product;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private final String query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private Product(String product, String query) {
 | 
				
			||||||
 | 
								this.product = product;
 | 
				
			||||||
 | 
								this.query = query;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							protected boolean matchesProduct(String product) {
 | 
				
			||||||
 | 
								return this.product.equalsIgnoreCase(product);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public String getQuery() {
 | 
				
			||||||
 | 
								return this.query;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public static Product forProduct(String product) {
 | 
				
			||||||
 | 
								for (Product candidate : values()) {
 | 
				
			||||||
 | 
									if (candidate.matchesProduct(product)) {
 | 
				
			||||||
 | 
										return candidate;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,12 +22,15 @@ import javax.sql.DataSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.junit.Before;
 | 
					import org.junit.Before;
 | 
				
			||||||
import org.junit.Test;
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					import org.springframework.boot.actuate.health.DataSourceHealthIndicator.Product;
 | 
				
			||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
 | 
					import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
 | 
				
			||||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
					import org.springframework.jdbc.core.JdbcTemplate;
 | 
				
			||||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
 | 
					import org.springframework.jdbc.datasource.DriverManagerDataSource;
 | 
				
			||||||
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
 | 
					import org.springframework.jdbc.datasource.SingleConnectionDataSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.hamcrest.Matchers.equalTo;
 | 
				
			||||||
import static org.hamcrest.Matchers.notNullValue;
 | 
					import static org.hamcrest.Matchers.notNullValue;
 | 
				
			||||||
 | 
					import static org.hamcrest.Matchers.nullValue;
 | 
				
			||||||
import static org.junit.Assert.assertEquals;
 | 
					import static org.junit.Assert.assertEquals;
 | 
				
			||||||
import static org.junit.Assert.assertNotNull;
 | 
					import static org.junit.Assert.assertNotNull;
 | 
				
			||||||
import static org.junit.Assert.assertThat;
 | 
					import static org.junit.Assert.assertThat;
 | 
				
			||||||
| 
						 | 
					@ -97,4 +100,16 @@ public class DataSourceHealthIndicatorTests {
 | 
				
			||||||
		verify(connection, times(2)).close();
 | 
							verify(connection, times(2)).close();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Test
 | 
				
			||||||
 | 
						public void productLooksups() throws Exception {
 | 
				
			||||||
 | 
							assertThat(Product.forProduct("newone"), nullValue());
 | 
				
			||||||
 | 
							assertThat(Product.forProduct("HSQL Database Engine"), equalTo(Product.HSQLDB));
 | 
				
			||||||
 | 
							assertThat(Product.forProduct("Oracle"), equalTo(Product.ORACLE));
 | 
				
			||||||
 | 
							assertThat(Product.forProduct("Apache Derby"), equalTo(Product.DERBY));
 | 
				
			||||||
 | 
							assertThat(Product.forProduct("DB2"), equalTo(Product.DB2));
 | 
				
			||||||
 | 
							assertThat(Product.forProduct("DB2/LINUXX8664"), equalTo(Product.DB2));
 | 
				
			||||||
 | 
							assertThat(Product.forProduct("Informix Dynamic Server"),
 | 
				
			||||||
 | 
									equalTo(Product.INFORMIX));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue