Olap4j-xmlaserver

From www.b-kaempgen.de
Jump to: navigation, search

Info

Tipps for installation

  • Install:
    • git clone git://github.com/olap4j/olap4j-xmlaserver.git
    • Import into Eclipse as Java Project
    • Add Dynamic Web Project Facet
    • Make src/main/java as source folder
    • Maven: see ( mvn clean install
    • Deployment assembly, library: olap4j, olap4ld added
  • I manually created a dynamic web project in Eclipse
  • In there, I copied all files from olap4j-xmlaserver master
  • Then I manually added libraries to WEB-INF/lib that xmlaserver relied upon:

commons-collections.jar

commons-dbcp.jar

commons-pool.jar

log4j.jar

nxparser-1.2.3.jar

olap4j-xmlaserver-0.0.1-SNAPSHOT.jar

saxon-9.2.jar

servlet-api.jar

xercesImpl.jar

...

Example web.xml to connect with olap4ld

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app>
	<display-name>XMLA Server</display-name>
	
	<servlet>
		<servlet-name>xmla</servlet-name>
		<servlet-class>mondrian.xmla.impl.Olap4jXmlaServlet</servlet-class>
		
		<init-param>
			<param-name>OlapDriverUsePreConfiguredDiscoverDatasourcesResponse</param-name>
			<param-value>true</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverDiscoverDatasources.dataSourceName</param-name>
			<param-value>[XMLA olap4ld]</param-value>
		</init-param>
		
		<init-param>
			<param-name>OlapDriverDiscoverDatasources.dataSourceInfo</param-name>
			<param-value>[LdCatalogSchema]</param-value>
		</init-param>
		<init-param>
			<param-name>OlapDriverDiscoverDatasources.url</param-name>
			<param-value>@datasourceUrl@</param-value>
		</init-param>
		<init-param>
			<param-name>OlapDriverDiscoverDatasources.providerType</param-name>
			<param-value>TDP</param-value>
		</init-param>
		
		<init-param>
			<param-name>OlapDriverDiscoverDatasources.authenticationMode</param-name>
			<param-value>Unauthenticated</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverMaxNumConnectionsPerUser</param-name>
			<param-value>15</param-value>
		</init-param>
				
		<init-param>
			<param-name>OlapDriverClassName</param-name>
			<param-value>org.olap4j.driver.olap4ld.Olap4ldDriver</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverConnectionString</param-name>
			<param-value>jdbc:ld://olap4ld;Catalog=LdCatalog;JdbcDrivers=com.mysql.jdbc.Driver;Server=http://;Database=EMBEDDEDSESAME;Datastructuredefinitions=;Datasets=;</param-value>
		</init-param>
		
		<init-param>
			<param-name>OlapDriverConnectionProperty.Prefix</param-name>
			<param-value>@connectionPrefix@</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverConnectionProperty.FetchLevelProperties</param-name>
			<param-value>false</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverConnectionProperty.FetchMemberProperties</param-name>
			<param-value>false</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverConnectionProperty.FetchMembers</param-name>
			<param-value>true</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverConnectionProperty.QueryTimeoutMs</param-name>
			<param-value>@queryTimeout@</param-value>
		</init-param>
		
		<init-param>
			<param-name>OlapDriverConnectionProperty.AuthenticationProvider</param-name>
			<param-value>com.someotherclass.XmlaAuthenticationProvider</param-value>
		</init-param>

		<init-param>
			<param-name>OlapDriverConnectionProperty.ConnectionTimeoutMs</param-name>
			<param-value>@connectionTimeout@</param-value>
		</init-param>
		
		<init-param>
			<param-name>OlapDriverConnectionProperty.TotalCellLimit</param-name>
			<param-value>@totalCellLimit@</param-value>
		</init-param>
		
		<init-param>
			<param-name>OlapDriverConnectionProperty.PerPivotCellLimit</param-name>
			<param-value>@perPivotCellLimit@</param-value>
		</init-param>
    
		<init-param>
			<param-name>OlapDriverConnectionProperty.Source</param-name>
			<param-value>Excel</param-value>
		</init-param>
        
        <init-param>
            <param-name>IdleConnectionsTimeoutMinutes</param-name>
            <param-value>@idleConnectionCleanupTimeout@</param-value>
        </init-param>
        
        <init-param>
            <param-name>EnableConnectionReuse</param-name>
            <param-value>@enableConnectionsReuse@</param-value>
        </init-param>
        
        <init-param>
            <param-name>EnableCubesMetadataPrefetch</param-name>
            <param-value>@enableCubesMetadataPrefetch@</param-value>
        </init-param>
	</servlet>

	<servlet-mapping>
		<servlet-name>xmla</servlet-name>
		<url-pattern>/xmla/*</url-pattern>
	</servlet-mapping>
</web-app>

Required modification: proper restriction to discover requests

  • xmla-server would not add proper restrictions to discover requests which would not allow olap4ld

to know the cube to query. (in RowsetDefinition).

Required modification: cube name pattern wildcard

  • Problem: Apparently, since cube name pattern (restrictions) is a wildcard, a list of values is stored. Therefore,

when querying for cubes in xmla-server, I check whether restrictions is a list:

				// Get cube manually
				Iterable<Cube> cubelist;
				// We have to consider that with xmla4js, this always is a list.
				String cubename;
				if (this.restrictions
						.get("CUBE_NAME") instanceof List) {
					List cuberestrictionlist = (List) this.restrictions
							.get("CUBE_NAME");
					cubename = cuberestrictionlist.get(0).toString();
				} else {
					cubename = this.restrictions
							.get("CUBE_NAME").toString();
				}
				if (cubename != null) {
					Cube mycube = schema.getCubes().get(
							cubename);
					ArrayList<Cube> newlist = new ArrayList<Cube>();
					newlist.add(mycube);
					cubelist = newlist;
				} else {
					cubelist = filter(sortedCubes(schema), cubeNameCond);
				}

Problem: Pooling of data sources

  • After some queries, we only get "Creating new connection for user [null] and session [<no_session>]"

and the program hangs.

  • I try to create a test case that reproduces the problem. - *done*
  • We now debug the problem:
    • Apparently, if we run the Xmla-Testcase several times, we always run into a "deadlock"
    • When this happens, we can suspend "Daemon Thread [http-8080-2] and see that probably

Object.wait (long) line: not available [native method] GenericObjectPool$Latch(Object).wait() GenericObjectPool.borrowObject() ... the problem is.

    • Trial: Connection connection = bds.getConnection();
      • give bds maybe testOnBorrow = true;
  • If I call the number of "Connect Olap4LdDriver." logs, one can assume that it is about the 15 max

connections. Apparently, we create 15 connections, do not reuse any connections and do not close others.

  • "OlapConnection mondrian.xmla.impl.Olap4jXmlaServlet.Olap4jPoolingConnectionFactory.getConnection(String

catalog, String schema, String roleName, Properties props) throws SQLException" ist synchronisiert (siehe http://openbook.galileocomputing.de/javainsel9/javainsel_14_005.htm#mj1bb85cdbf7de3e53c2f4909006721fe5),

  • Workaround in "OlapConnection mondrian.xmla.impl.Olap4jXmlaServlet.Olap4jPoolingConnectionFactory.getConnection(String catalog, String schema, String roleName, Properties props) throws SQLException":
            synchronized (datasourcesPool) {
                bds = datasourcesPool.get(dataSourceKey);
                // Workaround - simply close any bds
                if (bds != null) {
                	bds.close();
                	bds = null;
                }
                if (bds == null) {
                    bds = new BasicDataSource();
                    for (Map.Entry entry : connProperties.entrySet()) {
                        bds.addConnectionProperty(
                            (String) entry.getKey(),
                            (String) entry.getValue());
                    }
                    bds.setDefaultReadOnly(true);
                    bds.setDriverClassName(olap4jDriverClassName);
                    bds.setPassword(pwd);
                    bds.setUsername(user);
                    bds.setUrl(olap4jDriverConnectionString);
                    bds.setPoolPreparedStatements(false);
                    bds.setMaxIdle(maxPerUserConnectionCount);
                    bds.setMaxActive(maxPerUserConnectionCount);
                    bds.setMinEvictableIdleTimeMillis(
                        idleConnectionsCleanupTimeoutMs);
                    bds.setAccessToUnderlyingConnectionAllowed(true);
                    bds.setInitialSize(1);
                    bds.setTimeBetweenEvictionRunsMillis(60000);
                    if (catalog != null) {
                        bds.setDefaultCatalog(catalog);
                    }
                    datasourcesPool.put(dataSourceKey, bds);
                }
            }