Skip to content

Commit

Permalink
Fixes bug 3233181 in the XMLA driver. Refactored the way username and…
Browse files Browse the repository at this point in the history
… password are passed to the url. Should allow us later to easily implement user sessions.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@427 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
lucboudreau committed Mar 24, 2011
1 parent 0a2e5c6 commit 09ef658
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 116 deletions.
65 changes: 32 additions & 33 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
import org.xml.sax.SAXException;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.*;
import java.sql.*;
import java.util.*;
import java.util.Map.*;
Expand Down Expand Up @@ -79,7 +78,7 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
/**
* URL of the HTTP server to which to send XML requests.
*/
final URL serverUrl;
final XmlaOlap4jServerInfos serverInfos;

private Locale locale;

Expand Down Expand Up @@ -117,6 +116,8 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
*/
private NamedList<XmlaOlap4jDatabase> olapDatabases;

private final URL serverUrlObject;

/**
* This is a private property used for development only.
* Enabling it makes the connection print out all queries
Expand Down Expand Up @@ -163,7 +164,7 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
this.driver = driver;
this.proxy = proxy;

Map<String, String> map = parseConnectString(url, info);
final Map<String, String> map = parseConnectString(url, info);

this.databaseName =
map.get(XmlaOlap4jDriver.Property.Database.name());
Expand All @@ -175,36 +176,42 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
map.get(XmlaOlap4jDriver.Property.Schema.name());

// Set URL of HTTP server.
String serverUrl = map.get(XmlaOlap4jDriver.Property.Server.name());
final String serverUrl =
map.get(XmlaOlap4jDriver.Property.Server.name());
if (serverUrl == null) {
throw getHelper().createException(
"Connection property '"
+ XmlaOlap4jDriver.Property.Server.name()
+ "' must be specified");
}

// Basic authentication. Make sure the credentials passed as standard
// JDBC parameters override any credentials already included in the URL
// as part of the standard URL scheme.
if (map.containsKey("user") && map.containsKey("password")) {
serverUrl = serverUrl.replaceFirst(
":\\/\\/([^@]*@){0,1}",
"://"
+ map.get("user")
+ ":"
+ map.get("password")
+ "@");
try {
this.serverUrlObject = new URL(serverUrl);
} catch (MalformedURLException e) {
throw getHelper().createException(e);
}

// Initialize the SOAP cache if needed
initSoapCache(map);

try {
this.serverUrl = new URL(serverUrl);
} catch (MalformedURLException e) {
throw getHelper().createException(
"Error while creating connection", e);
}
this.serverInfos =
new XmlaOlap4jServerInfos() {
private String sessionId = null;
public String getUsername() {
return map.get("user");
}
public String getPassword() {
return map.get("password");
}
public URL getUrl() {
return serverUrlObject;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
};

this.olap4jDatabaseMetaData =
factory.newDatabaseMetaData(this);
Expand Down Expand Up @@ -724,16 +731,7 @@ Element executeMetadataRequest(String request) throws OlapException {
System.out.println(request);
}
try {
bytes = proxy.get(serverUrl, request);
} catch (IOException e) {
/*
* FIXME This type of exception should not reach this point.
* It was maintained because some other proxy implementations
* exists out there that still throw an IOException arround.
* This was a bad design which we will fix at some point but not
* before the 1.0 release.
*/
throw getHelper().createException(e);
bytes = proxy.get(serverInfos, request);
} catch (XmlaOlap4jProxyException e) {
throw getHelper().createException(
"This connection encountered an exception while executing a query.",
Expand Down Expand Up @@ -836,6 +834,7 @@ public String generateRequest(
+ " <Discover xmlns=\"urn:schemas-microsoft-com:xml-analysis\"\n"
+ " SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
+ " <RequestType>");

buf.append(metadataRequest.name());
buf.append(
"</RequestType>\n"
Expand Down
8 changes: 4 additions & 4 deletions src/org/olap4j/driver/xmla/XmlaOlap4jDriver.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
// $Id:$
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2010 Julian Hyde
// Copyright (C) 2007-2011 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand All @@ -11,7 +12,6 @@
import org.olap4j.driver.xmla.proxy.*;
import org.olap4j.impl.Olap4jUtil;

import java.net.*;
import java.sql.*;
import java.util.*;
import java.util.concurrent.*;
Expand Down Expand Up @@ -262,13 +262,13 @@ protected XmlaOlap4jProxy createProxy(Map<String, String> map) {
*/
public static Future<byte[]> getFuture(
final XmlaOlap4jProxy proxy,
final URL url,
final XmlaOlap4jServerInfos serverInfos,
final String request)
{
return executor.submit(
new Callable<byte[]>() {
public byte[] call() throws Exception {
return proxy.get(url, request);
return proxy.get(serverInfos, request);
}
}
);
Expand Down
45 changes: 45 additions & 0 deletions src/org/olap4j/driver/xmla/XmlaOlap4jServerInfos.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
// $Id:$
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2011 Julian Hyde and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package org.olap4j.driver.xmla;

import java.net.URL;

/**
* Common set of functions for an XMLA URL Provider.
* @version $Id:$
*/
public interface XmlaOlap4jServerInfos {
/**
* Returns the URL to use.
* @return the url.
*/
URL getUrl();
/**
* Returns the username to use with the URL.
* @return the username.
*/
String getUsername();
/**
* Returns the password to use with the URL.
* @return the password.
*/
String getPassword();
/**
* Returns a unique sesison ID to use.
* @return the session id.
*/
String getSessionId();
/**
* Stores the session id on the server.
* @param sessionId The session id to use.
*/
void setSessionId(String sessionId);
}
// End XmlaOlap4jServerInfos.java
8 changes: 3 additions & 5 deletions src/org/olap4j/driver/xmla/XmlaOlap4jStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2010 Julian Hyde
// Copyright (C) 2007-2011 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package org.olap4j.driver.xmla;

import org.olap4j.*;
import org.olap4j.mdx.SelectNode;
import org.olap4j.mdx.ParseTreeNode;
import org.olap4j.mdx.ParseTreeWriter;
import org.olap4j.mdx.*;

import java.sql.*;
import java.io.*;
Expand Down Expand Up @@ -326,7 +324,7 @@ public CellSet executeOlapQuery(String mdx) throws OlapException {

this.future =
olap4jConnection.proxy.submit(
olap4jConnection.serverUrl, request);
olap4jConnection.serverInfos, request);
openCellSet = olap4jConnection.factory.newCellSet(this);
}
// Release the monitor before calling populate, so that cancel can
Expand Down
30 changes: 20 additions & 10 deletions src/org/olap4j/driver/xmla/proxy/XmlaOlap4jAbstractHttpProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2010 Julian Hyde
// Copyright (C) 2007-2011 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand All @@ -17,6 +17,7 @@
import org.olap4j.OlapException;
import org.olap4j.driver.xmla.XmlaHelper;
import org.olap4j.driver.xmla.XmlaOlap4jDriver;
import org.olap4j.driver.xmla.XmlaOlap4jServerInfos;
import org.olap4j.driver.xmla.cache.XmlaOlap4jCache;

/**
Expand Down Expand Up @@ -68,8 +69,10 @@ protected XmlaOlap4jAbstractHttpProxy() {
* @param request Request string
* @return Response
*/
abstract public byte[] getResponse(URL url, String request)
throws XmlaOlap4jProxyException;
abstract public byte[] getResponse(
XmlaOlap4jServerInfos serverInfos,
String request)
throws XmlaOlap4jProxyException;


/**
Expand All @@ -80,7 +83,7 @@ abstract public byte[] getResponse(URL url, String request)
* @return Future object representing the submitted job
*/
abstract public Future<byte[]> getResponseViaSubmit(
URL url,
XmlaOlap4jServerInfos serverInfos,
String request);

/**
Expand Down Expand Up @@ -147,13 +150,17 @@ public void setCache(
}

// implement XmlaOlap4jProxy
public byte[] get(URL url, String request) throws XmlaOlap4jProxyException {
public byte[] get(
XmlaOlap4jServerInfos serverInfos,
String request)
throws XmlaOlap4jProxyException
{
byte[] response = null;
// Tries to fetch from cache
try {
response =
getFromCache(
url,
serverInfos.getUrl(),
request.getBytes(getEncodingCharsetName()));
// Returns the cached value if found
if (response != null) {
Expand All @@ -166,12 +173,12 @@ public byte[] get(URL url, String request) throws XmlaOlap4jProxyException {
}

// Executes the query
response = getResponse(url, request);
response = getResponse(serverInfos, request);

try {
// Adds to cache
addToCache(
url,
serverInfos.getUrl(),
request.getBytes(getEncodingCharsetName()),
response);
// Returns result
Expand Down Expand Up @@ -218,14 +225,17 @@ private void addToCache(URL url, byte[] request, byte[] response)
}

// implement XmlaOlap4jProxy
public Future<byte[]> submit(final URL url, final String request) {
public Future<byte[]> submit(
final XmlaOlap4jServerInfos serverInfos,
final String request)
{
// The submit operation doesn't need to be cached yet, since it will
// call the get operation to fetch the data later on. It will get cached
// then.
//
// I still overridden the submit method in case we need some caching
// done in the end. - Luc
return getResponseViaSubmit(url, request);
return getResponseViaSubmit(serverInfos, request);
}

/**
Expand Down
27 changes: 21 additions & 6 deletions src/org/olap4j/driver/xmla/proxy/XmlaOlap4jHttpProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.concurrent.*;

import org.olap4j.driver.xmla.XmlaOlap4jDriver;
import org.olap4j.driver.xmla.XmlaOlap4jServerInfos;
import org.olap4j.impl.Base64;

/**
Expand All @@ -39,16 +40,19 @@ public class XmlaOlap4jHttpProxy extends XmlaOlap4jAbstractHttpProxy
*
* @param driver Driver
*/
public XmlaOlap4jHttpProxy(XmlaOlap4jDriver driver) {
public XmlaOlap4jHttpProxy(
XmlaOlap4jDriver driver)
{
this.driver = driver;
}

@Override
public byte[] getResponse(URL url, String request)
public byte[] getResponse(XmlaOlap4jServerInfos serverInfos, String request)
throws XmlaOlap4jProxyException
{
URLConnection urlConnection = null;
try {
URL url = serverInfos.getUrl();
// Open connection to manipulate the properties
urlConnection = url.openConnection();
urlConnection.setDoOutput(true);
Expand Down Expand Up @@ -87,9 +91,20 @@ public byte[] getResponse(URL url, String request)
}

// Encode credentials for basic authentication
if (url.getUserInfo() != null) {
StringBuilder sb = new StringBuilder();
if (serverInfos.getUsername() != null
&& serverInfos.getPassword() != null)
{
sb.append(serverInfos.getUsername());
sb.append(":");
sb.append(serverInfos.getPassword());
} else if (url.getUserInfo() != null) {
sb.append(url.getUserInfo());
}
if (!sb.toString().equals("")) {
String encoding =
Base64.encodeBytes(url.getUserInfo().getBytes(), 0);
Base64.encodeBytes(
sb.toString().getBytes(), 0);
urlConnection.setRequestProperty(
"Authorization", "Basic " + encoding);
}
Expand Down Expand Up @@ -149,10 +164,10 @@ public byte[] getResponse(URL url, String request)

@Override
public Future<byte[]> getResponseViaSubmit(
final URL url,
final XmlaOlap4jServerInfos serverInfos,
final String request)
{
return XmlaOlap4jDriver.getFuture(this, url, request);
return XmlaOlap4jDriver.getFuture(this, serverInfos, request);
}

// implement XmlaOlap4jProxy
Expand Down
Loading

0 comments on commit 09ef658

Please sign in to comment.