throws SQLException, NamingException
{
// use the datasource property to connect to the database
Util.PropertyList properties =
TestContext.instance().getConnectionProperties().clone();
final Dialect dialect = TestContext.instance().getDialect();
if (dialect.getDatabaseProduct() == Dialect.DatabaseProduct.ACCESS) {
// Access doesn't accept user/password, so this test is pointless.
return;
}
final String jdbcUser =
properties.get(RolapConnectionProperties.JdbcUser.name());
final String jdbcPassword =
properties.get(RolapConnectionProperties.JdbcPassword.name());
if (jdbcUser == null || jdbcPassword == null) {
// Can only run this test if username and password are explicit.
return;
}
// Define a data source with bogus user and password.
properties.put(
RolapConnectionProperties.JdbcUser.name(),
"bogususer");
properties.put(
RolapConnectionProperties.JdbcPassword.name(),
"boguspassword");
properties.put(
RolapConnectionProperties.PoolNeeded.name(),
"false");
final StringBuilder buf = new StringBuilder();
final DataSource dataSource =
RolapConnection.createDataSource(null, properties, buf);
final String desc = buf.toString();
assertTrue(desc, desc.startsWith("Jdbc="));
assertTrue(
desc,
desc.indexOf("JdbcUser=bogususer; JdbcPassword=boguspassword")
>= 0);
final String jndiName = "jndiDataSource";
THREAD_INITIAL_CONTEXT.set(
new InitialContext() {
public Object lookup(String str) {
return str.equals(jndiName)
? dataSource
: null;
}
}
);
// Create a property list that we will use for the actual mondrian
// connection. Replace the original JDBC info with the data source we
// just created.
final Util.PropertyList properties2 = new Util.PropertyList();
for (Pair<String, String> entry : properties) {
properties2.put(entry.getKey(), entry.getValue());
}
properties2.remove(RolapConnectionProperties.Jdbc.name());
properties2.put(
RolapConnectionProperties.DataSource.name(),
jndiName);
// With JdbcUser and JdbcPassword credentials in the mondrian connect
// string, the data source's "user" and "password" properties are
// overridden and the connection succeeds.
properties2.put(
RolapConnectionProperties.JdbcUser.name(),
jdbcUser);
properties2.put(
RolapConnectionProperties.JdbcPassword.name(),
jdbcPassword);
mondrian.olap.Connection connection = null;
try {
connection =
DriverManager.getConnection(properties2, null);
Query query = connection.parseQuery("select from [Sales]");
final Result result = connection.execute(query);
assertNotNull(result);
} finally {
if (connection != null) {
connection.close();
connection = null;
}
}
// If we don't specify JdbcUser and JdbcPassword in the mondrian
// connection properties, mondrian uses the data source's
// bogus credentials, and the connection fails.
properties2.remove(RolapConnectionProperties.JdbcUser.name());
properties2.remove(RolapConnectionProperties.JdbcPassword.name());
for (String poolNeeded : Arrays.asList("false", "true")) {
// Important to test with & without pooling. Connection pools
// typically do not let you change user, so it's important that
// mondrian handles these right.
properties2.put(
RolapConnectionProperties.PoolNeeded.name(), poolNeeded);
try {
connection = DriverManager.getConnection(properties2, null);
fail("Expected exception");
} catch (MondrianException e) {
final String s = TestContext.getStackTrace(e);
assertTrue(
s,
s.indexOf(
"Error while creating SQL connection: "
+ "DataSource=jndiDataSource") >= 0);
switch (dialect.getDatabaseProduct()) {
case DERBY:
assertTrue(
s,
s.indexOf(
"Caused by: java.sql.SQLException: "