use of mondrian.olap.MondrianException in project mondrian by pentaho.
the class SegmentLoader method createExecuteSql.
/**
* Creates and executes a SQL statement to retrieve the set of cells
* specified by a GroupingSetsList.
*
* <p>This method may be overridden in tests.
*
* @param cellRequestCount Number of missed cells that led to this request
* @param groupingSetsList Grouping
* @param compoundPredicateList Compound predicate list
* @return An executed SQL statement, or null
*/
SqlStatement createExecuteSql(int cellRequestCount, final GroupingSetsList groupingSetsList, List<StarPredicate> compoundPredicateList) {
RolapStar star = groupingSetsList.getStar();
Pair<String, List<SqlStatement.Type>> pair = AggregationManager.generateSql(groupingSetsList, compoundPredicateList);
final Locus locus = new SqlStatement.StatementLocus(Locus.peek().execution, "Segment.load", "Error while loading segment", SqlStatementEvent.Purpose.CELL_SEGMENT, cellRequestCount);
// When caching is enabled, we must register the SQL statement
// in the index. We don't want to cancel SQL statements that are shared
// across threads unless it is safe.
final Util.Functor1<Void, Statement> callbackWithCaching = new Util.Functor1<Void, Statement>() {
public Void apply(final Statement stmt) {
cacheMgr.execute(new SegmentCacheManager.Command<Void>() {
public Void call() throws Exception {
boolean atLeastOneActive = false;
for (Segment seg : groupingSetsList.getDefaultSegments()) {
final SegmentCacheIndex index = cacheMgr.getIndexRegistry().getIndex(seg.star);
// then.
if (index.contains(seg.getHeader())) {
index.linkSqlStatement(seg.getHeader(), stmt);
atLeastOneActive = true;
}
if (!atLeastOneActive) {
// knows to stop.
throw new AbortException();
}
}
return null;
}
public Locus getLocus() {
return locus;
}
});
return null;
}
};
// When using no cache, we register the SQL statement directly
// with the execution instance for cleanup.
final Util.Functor1<Void, Statement> callbackNoCaching = new Util.Functor1<Void, Statement>() {
public Void apply(final Statement stmt) {
locus.execution.registerStatement(locus, stmt);
return null;
}
};
try {
return RolapUtil.executeQuery(star.getDataSource(), pair.left, pair.right, 0, 0, locus, -1, -1, // cache the segments or not.
MondrianProperties.instance().DisableCaching.get() ? callbackNoCaching : callbackWithCaching);
} catch (Throwable t) {
if (Util.getMatchingCause(t, AbortException.class) != null) {
return null;
} else {
throw new MondrianException("Failed to load segment form SQL", t);
}
}
}
use of mondrian.olap.MondrianException in project mondrian by pentaho.
the class AggTableManager method loadRolapStarAggregates.
/**
* This method loads and/or reloads the aggregate tables.
* <p>
* NOTE: At this point all RolapStars have been made for this
* schema (except for dynamically added cubes which I am going
* to ignore for right now). So, All stars have their columns
* and their BitKeys can be generated.
*
* @throws SQLException
*/
private void loadRolapStarAggregates() throws SQLException {
ListRecorder msgRecorder = new ListRecorder();
try {
DefaultRules rules = DefaultRules.getInstance();
JdbcSchema db = getJdbcSchema();
// calls to other instances of AggTableManager.finalCleanUp()
synchronized (db) {
// fix for MONDRIAN-496
// flush any existing usages of the jdbc schema, so we
// don't accidentally use another star's metadata
db.flushUsages();
// loads tables, not their columns
db.load();
loop: for (RolapStar star : getStars()) {
// This removes any AggStars from any previous invocation of
// this method (if any)
star.prepareToLoadAggregates();
List<ExplicitRules.Group> aggGroups = getAggGroups(star);
for (ExplicitRules.Group group : aggGroups) {
group.validate(msgRecorder);
}
String factTableName = getFactTableName(star);
JdbcSchema.Table dbFactTable = db.getTable(factTableName);
if (dbFactTable == null) {
msgRecorder.reportWarning("No Table found for fact name=" + factTableName);
continue loop;
}
// For each column in the dbFactTable, figure out it they
// are measure or foreign key columns
bindToStar(dbFactTable, star, msgRecorder);
String schema = dbFactTable.table.schema;
for (JdbcSchema.Table dbTable : db.getTables()) {
String name = dbTable.getName();
// this table name.
if (ExplicitRules.excludeTable(name, aggGroups)) {
continue;
}
// First see if there is an ExplicitRules match. If so,
// then if all of the columns match up, then make an
// AggStar. On the other hand, if there is no
// ExplicitRules match, see if there is a Default
// match. If so and if all the columns match up, then
// also make an AggStar.
ExplicitRules.TableDef tableDef = ExplicitRules.getIncludeByTableDef(name, aggGroups);
boolean makeAggStar = false;
int approxRowCount = Integer.MIN_VALUE;
// Is it handled by the ExplicitRules
if (tableDef != null) {
// load columns
dbTable.load();
makeAggStar = tableDef.columnsOK(star, dbFactTable, dbTable, msgRecorder);
approxRowCount = tableDef.getApproxRowCount();
}
if (!makeAggStar && MondrianProperties.instance().ReadAggregates.get()) {
// Is it handled by the DefaultRules
if (rules.matchesTableName(factTableName, name)) {
// load columns
dbTable.load();
makeAggStar = rules.columnsOK(star, dbFactTable, dbTable, msgRecorder);
}
}
if (makeAggStar) {
dbTable.setTableUsageType(JdbcSchema.TableUsageType.AGG);
dbTable.table = new MondrianDef.Table(schema, name, // null alias
null, // don't know about table hints
null);
AggStar aggStar = AggStar.makeAggStar(star, dbTable, msgRecorder, approxRowCount);
if (aggStar.getSize() > 0) {
star.addAggStar(aggStar);
} else {
getLogger().warn(mres.AggTableZeroSize.str(aggStar.getFactTable().getName(), factTableName));
}
}
// Note: if the dbTable name matches but the columnsOK
// does not, then this is an error and the aggregate
// tables can not be loaded.
// We do not "reset" the column usages in the dbTable
// allowing it maybe to match another rule.
}
}
}
} catch (RecorderException ex) {
throw new MondrianException(ex);
} finally {
msgRecorder.logInfoMessage(getLogger());
msgRecorder.logWarningMessage(getLogger());
msgRecorder.logErrorMessage(getLogger());
if (msgRecorder.hasErrors()) {
throw mres.AggLoadingExceededErrorCount.ex(msgRecorder.getErrorCount());
}
}
}
use of mondrian.olap.MondrianException in project mondrian by pentaho.
the class RolapConnectionTest method testDataSourceOverrideUserPass.
public void testDataSourceOverrideUserPass() throws SQLException, NamingException {
// use the datasource property to connect to the database
Util.PropertyList properties = spy(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") >= 0);
verify(properties, atLeastOnce()).get(RolapConnectionProperties.JdbcPassword.name());
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: " + "Schema 'BOGUSUSER' does not exist") >= 0);
break;
case ORACLE:
assertTrue(s, s.indexOf("Caused by: java.sql.SQLException: ORA-01017: " + "invalid username/password; logon denied") >= 0);
break;
case MYSQL:
case MARIADB:
assertTrue(s, s.indexOf("Caused by: java.sql.SQLException: Access denied " + "for user 'bogususer'") >= 0);
break;
case POSTGRESQL:
assertTrue(s, s.indexOf("Caused by: org.postgresql.util.PSQLException: " + "FATAL: password authentication failed for " + "user \"bogususer\"") >= 0);
break;
}
} finally {
if (connection != null) {
connection.close();
connection = null;
}
}
}
}
use of mondrian.olap.MondrianException in project mondrian by pentaho.
the class RolapNativeSqlInjectionTest method testMondrian2436.
public void testMondrian2436() {
String mdxQuery = "" + "select {[Measures].[Store Sales]} on columns, " + "filter([Customers].[Name].Members, (([Measures].[Store Sales]) > '(select 1000)')) on rows " + "from [Sales]";
TestContext context = getTestContext().withFreshConnection();
try {
context.executeQuery(mdxQuery);
} catch (MondrianException e) {
assertNotNull("MondrianEvaluationException is expected on invalid filter condition", e.getCause());
assertEquals("Expected to get decimal, but got (select 1000)", e.getCause().getMessage());
return;
} finally {
context.close();
}
fail("[Store Sales] filtering should not work for non-valid decimals");
}
use of mondrian.olap.MondrianException in project pentaho-platform by pentaho.
the class PentahoXmlaServletTest method createConnectionFactory.
@Test
public void createConnectionFactory() throws Exception {
ISecurityHelper securityHelper = mock(ISecurityHelper.class);
SecurityHelper.setMockInstance(securityHelper);
when(securityHelper.runAsSystem(any((Callable.class)))).thenReturn(DATASOURCE_XML);
IMondrianCatalogService catalogService = mock(MondrianCatalogHelper.class);
MondrianCatalog mondrianCatalog = mock(MondrianCatalog.class);
when(mondrianCatalog.getDataSourceInfo()).thenReturn("DataSource=foo");
doReturn(mondrianCatalog).when(catalogService).getCatalog(anyString(), anyObject());
PowerMockito.mockStatic(DriverManager.class);
when(DriverManager.getConnection(anyString(), anyObject())).thenReturn(mock(RolapConnection.class));
PentahoSystem.registerObject(catalogService);
PentahoXmlaServlet xmlaServlet = spy(new PentahoXmlaServlet());
XmlaHandler.ConnectionFactory connectionFactory = xmlaServlet.createConnectionFactory(mock(ServletConfig.class));
Properties properties = new Properties();
properties.put("DataSource", "bogus");
try {
connectionFactory.getConnection("SampleData", "SampleData", "baz", properties);
} catch (MondrianException exception) {
// ignored
}
try {
connectionFactory.getConnection("SampleData", "SampleData", "baz", properties);
} catch (MondrianException exception) {
// ignored
}
// We verify that only one Catalog Locator is created for multiple requests
verify(xmlaServlet, times(1)).makeCatalogLocator(anyObject());
}
Aggregations