Search in sources :

Example 6 with MondrianException

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);
        }
    }
}
Also used : Statement(java.sql.Statement) Util(mondrian.olap.Util) AbortException(mondrian.rolap.agg.SegmentCacheManager.AbortException) SQLException(java.sql.SQLException) MondrianException(mondrian.olap.MondrianException) SegmentCacheIndex(mondrian.rolap.cache.SegmentCacheIndex) Locus(mondrian.server.Locus) MondrianException(mondrian.olap.MondrianException) AbortException(mondrian.rolap.agg.SegmentCacheManager.AbortException)

Example 7 with MondrianException

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());
        }
    }
}
Also used : RolapStar(mondrian.rolap.RolapStar) RecorderException(mondrian.recorder.RecorderException) ArrayList(java.util.ArrayList) List(java.util.List) MondrianException(mondrian.olap.MondrianException) ListRecorder(mondrian.recorder.ListRecorder)

Example 8 with MondrianException

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;
            }
        }
    }
}
Also used : Query(mondrian.olap.Query) Util(mondrian.olap.Util) InitialContext(javax.naming.InitialContext) DataSource(javax.sql.DataSource) Result(mondrian.olap.Result) Dialect(mondrian.spi.Dialect) MondrianException(mondrian.olap.MondrianException)

Example 9 with MondrianException

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");
}
Also used : TestContext(mondrian.test.TestContext) MondrianException(mondrian.olap.MondrianException)

Example 10 with MondrianException

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());
}
Also used : RolapConnection(mondrian.rolap.RolapConnection) ISecurityHelper(org.pentaho.platform.api.engine.ISecurityHelper) MondrianCatalog(org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalog) XmlaHandler(mondrian.xmla.XmlaHandler) ServletConfig(javax.servlet.ServletConfig) IMondrianCatalogService(org.pentaho.platform.plugin.action.mondrian.catalog.IMondrianCatalogService) Properties(java.util.Properties) MondrianException(mondrian.olap.MondrianException) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Aggregations

MondrianException (mondrian.olap.MondrianException)23 Util (mondrian.olap.Util)5 PostgreSqlDialect (mondrian.spi.impl.PostgreSqlDialect)5 Connection (mondrian.olap.Connection)4 RolapConnection (mondrian.rolap.RolapConnection)4 SQLException (java.sql.SQLException)3 Test (org.junit.Test)3 IMondrianCatalogService (org.pentaho.platform.plugin.action.mondrian.catalog.IMondrianCatalogService)3 FileNotFoundException (java.io.FileNotFoundException)2 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 ArrayList (java.util.ArrayList)2 Properties (java.util.Properties)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 Query (mondrian.olap.Query)2 AbortException (mondrian.rolap.agg.SegmentCacheManager.AbortException)2 SegmentCacheIndex (mondrian.rolap.cache.SegmentCacheIndex)2 Locus (mondrian.server.Locus)2 FileSystemException (org.apache.commons.vfs2.FileSystemException)2 XOMException (org.eigenbase.xom.XOMException)2