Skip to content

Commit

Permalink
Fixed issue 2018878. If a SOAP error is received from the server, it …
Browse files Browse the repository at this point in the history
…will be included in the exception that is thrown back at the end-user.

There is still an issue with some IOException that can reach the end-user layer. This is a no-no and will need to be fixed. I didn't fix it here since the MondrianInprocProxy implements the faulty interface. XmlaOlap4jProxy implementation should not throw any IOException, but should handle it's own exceptions and wrap them in XmlaOlap4jProxyException is necessary.

I've added a FIXME tag and will log a bug against it.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@119 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
lucboudreau committed Oct 6, 2008
1 parent 3b1e745 commit 19f9d9d
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 89 deletions.
4 changes: 4 additions & 0 deletions src/org/olap4j/OlapExceptionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public static OlapException createException(String msg) {
return new OlapException(msg);
}

public static OlapException createException(Throwable cause) {
return new OlapException(cause.getMessage(), cause);
}

public static OlapException createException(String msg, Throwable cause) {
return new OlapException(msg, cause);
}
Expand Down
17 changes: 10 additions & 7 deletions src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import org.olap4j.impl.Olap4jUtil;
import static org.olap4j.driver.xmla.XmlaOlap4jUtil.*;
import org.olap4j.metadata.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.*;
import org.w3c.dom.ls.*;
import org.xml.sax.SAXException;

import java.io.*;
Expand Down Expand Up @@ -107,8 +107,6 @@ void populate() throws OlapException {
findChild(body, SOAP_NS, "Fault");
if (fault != null) {
/*
Example:
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client.00HSBC01</faultcode>
<faultstring>XMLA connection datasource not found</faultstring>
Expand All @@ -123,10 +121,15 @@ void populate() throws OlapException {
</SOAP-ENV:Fault>
*/
// TODO: log doc to logfile
final Element faultstring = findChild(fault, null, "faultstring");
String message = faultstring.getTextContent();
// A message must include the fault XML content. This is the right
// and efficient way to do it, according to
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6181019
// They changed the node.getString() in java... ....
DOMImplementation impl = fault.getOwnerDocument().getImplementation();
DOMImplementationLS factory = (DOMImplementationLS) impl.getFeature("LS", "3.0");
LSSerializer serializer = factory.createLSSerializer();
throw OlapExceptionHelper.createException(
"XMLA provider gave exception: " + message);
"XMLA provider gave exception: " + serializer.writeToString(fault));
}
Element executeResponse =
findChild(body, XMLA_NS, "ExecuteResponse");
Expand Down
13 changes: 12 additions & 1 deletion src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,18 @@ Element xxx(String request) throws OlapException {
try {
bytes = proxy.get(serverUrl, request);
} catch (IOException e) {
throw OlapExceptionHelper.createException(null, 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 OlapExceptionHelper.createException(e);
} catch (XmlaOlap4jProxyException e) {
throw OlapExceptionHelper.createException(
"This connection encountered an exception while executing a query.",
e);
}
Document doc;
try {
Expand Down
51 changes: 31 additions & 20 deletions src/org/olap4j/driver/xmla/proxy/XmlaOlap4jAbstractHttpProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public abstract class XmlaOlap4jAbstractHttpProxy
* @throws IOException
*/
abstract public byte[] getResponse(URL url, String request)
throws IOException;
throws XmlaOlap4jProxyException;


/**
Expand All @@ -84,7 +84,7 @@ abstract public Future<byte[]> getResponseViaSubmit(
* @throws IOException An io exception gets thrown if the given url
* connection has not been opened yet.
*/
protected void useCookies(URLConnection urlConn) throws IOException {
protected void useCookies(URLConnection urlConn){
// Initializes the cookie manager
this.initCookieManager();

Expand All @@ -100,7 +100,7 @@ protected void useCookies(URLConnection urlConn) throws IOException {
* @throws IOException An io exception gets thrown if the given url
* connection has already been opened.
*/
protected void saveCookies(URLConnection urlConn) throws IOException {
protected void saveCookies(URLConnection urlConn){
// Initializes the cookie manager
this.initCookieManager();

Expand Down Expand Up @@ -151,29 +151,40 @@ public void setCache(Map<String,String> config, Map<String,String> properties)
}

// implement XmlaOlap4jProxy
public byte[] get(URL url, String request) throws IOException {
public byte[] get(URL url, String request) throws XmlaOlap4jProxyException {
byte[] response = null;
// Tries to fetch from cache
byte[] response =
getFromCache(
url,
request.getBytes(getEncodingCharsetName()));

// Returns the cached value if found
if (response != null) {
return response;
try {
response =
getFromCache(
url,
request.getBytes(getEncodingCharsetName()));
// Returns the cached value if found
if (response != null) {
return response;
}
} catch (IOException e) {
throw new XmlaOlap4jProxyException(
"An exception was encountered while browsing the proxy cache.",
e);
}

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

// Adds to cache
addToCache(
url,
request.getBytes(getEncodingCharsetName()),
response);

// Returns result
return response;
try {
// Adds to cache
addToCache(
url,
request.getBytes(getEncodingCharsetName()),
response);
// Returns result
return response;
} catch (IOException e) {
throw new XmlaOlap4jProxyException(
"An exception was encountered while saving a response in the proxy cache.",
e);
}
}


Expand Down
21 changes: 7 additions & 14 deletions src/org/olap4j/driver/xmla/proxy/XmlaOlap4jCookieManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,10 @@
*/
package org.olap4j.driver.xmla.proxy;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;

/**
* <p>CookieManager is a simple utility for handling cookies when working
Expand Down Expand Up @@ -88,7 +82,7 @@ public XmlaOlap4jCookieManager() {
* or IOException will be thrown
* @throws java.io.IOException Thrown if <i>conn</i> is not open.
*/
public void storeCookies(URLConnection conn) throws IOException {
public void storeCookies(URLConnection conn){

// Determines the domain from where these cookies are being sent
String domain = getDomainFromHost(conn.getURL().getHost());
Expand Down Expand Up @@ -164,7 +158,7 @@ public void storeCookies(URLConnection conn) throws IOException {
* @param conn a java.net.URLConnection - must NOT be open, or IOException will be thrown
* @throws java.io.IOException Thrown if <i>conn</i> has already been opened.
*/
public void setCookies(URLConnection conn) throws IOException {
public void setCookies(URLConnection conn){

// Determines the domain and path to retrieve the appropriate cookies
URL url = conn.getURL();
Expand Down Expand Up @@ -200,9 +194,8 @@ && isNotExpired((String) cookie.get(EXPIRES))) {
}
conn.setRequestProperty(COOKIE, cookieStringBuffer.toString());
} catch (java.lang.IllegalStateException ise) {
IOException ioe = new IOException(
throw new RuntimeException(
"Illegal State! Cookies cannot be set on a URLConnection that is already connected. Only call setCookies(java.net.URLConnection) AFTER calling java.net.URLConnection.connect().");
throw ioe;
}
}

Expand Down
95 changes: 51 additions & 44 deletions src/org/olap4j/driver/xmla/proxy/XmlaOlap4jHttpProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,59 +34,66 @@ public class XmlaOlap4jHttpProxy extends XmlaOlap4jAbstractHttpProxy
{
@Override
public byte[] getResponse(URL url, String request)
throws IOException
throws XmlaOlap4jProxyException
{
// Open connection to manipulate the properties
URLConnection urlConnection = url.openConnection();
urlConnection.setDoOutput(true);
try {
// Open connection to manipulate the properties
URLConnection urlConnection = url.openConnection();
urlConnection.setDoOutput(true);

// Set headers
urlConnection.setRequestProperty(
"content-type",
"text/xml");
urlConnection.setRequestProperty(
"User-Agent",
"Olap4j("
.concat(XmlaOlap4jDriver.VERSION)
.concat(")"));
urlConnection.setRequestProperty(
"Accept",
"text/xml;q=1");
urlConnection.setRequestProperty(
"Accept-Charset",
getEncodingCharsetName()
.concat(";q=1"));

// Encode credentials for basic authentication
if (url.getUserInfo() != null) {
String encoding =
Base64.encodeBytes(url.getUserInfo().getBytes(), 0);
// Set headers
urlConnection.setRequestProperty(
"Authorization", "Basic " + encoding);
}
"content-type",
"text/xml");
urlConnection.setRequestProperty(
"User-Agent",
"Olap4j("
.concat(XmlaOlap4jDriver.VERSION)
.concat(")"));
urlConnection.setRequestProperty(
"Accept",
"text/xml;q=1");
urlConnection.setRequestProperty(
"Accept-Charset",
getEncodingCharsetName()
.concat(";q=1"));

// Set correct cookies
this.useCookies(urlConnection);
// Encode credentials for basic authentication
if (url.getUserInfo() != null) {
String encoding =
Base64.encodeBytes(url.getUserInfo().getBytes(), 0);
urlConnection.setRequestProperty(
"Authorization", "Basic " + encoding);
}

// Send data (i.e. POST). Use same encoding as specified in the
// header.
final String encoding = getEncodingCharsetName();
urlConnection.getOutputStream().write(request.getBytes(encoding));
// Set correct cookies
this.useCookies(urlConnection);

// Get the response, again assuming default encoding.
InputStream is = urlConnection.getInputStream();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int count;
// Send data (i.e. POST). Use same encoding as specified in the
// header.
final String encoding = getEncodingCharsetName();
urlConnection.getOutputStream().write(request.getBytes(encoding));

while ((count = is.read(buf)) > 0) {
baos.write(buf, 0, count);
}
// Get the response, again assuming default encoding.
InputStream is = urlConnection.getInputStream();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int count;

// Save the returned cookies for later use
this.saveCookies(urlConnection);
while ((count = is.read(buf)) > 0) {
baos.write(buf, 0, count);
}

return baos.toByteArray();
// Save the returned cookies for later use
this.saveCookies(urlConnection);

return baos.toByteArray();
// All exceptions should be trapped here.
// The response will only be available here anyways.
} catch (Exception e) {
throw new XmlaOlap4jProxyException(
"This proxy encountered an exception while processing the query.",e);
}
}

@Override
Expand Down
16 changes: 13 additions & 3 deletions src/org/olap4j/driver/xmla/proxy/XmlaOlap4jProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,20 @@ public interface XmlaOlap4jProxy {
*
* @param url Target URL
* @param request Request string
* @return Response
* @throws IOException
* @return Response The byte array that contains the whole response
* from the server.
* @throws IOException This exception declaration will be removed soon.
* Don't catch this. Catch XmlaOlap4jProxyException instead.
* @throws XmlaOlap4jProxyException If anything occurs during the
* request execution.
*/
byte[] get(URL url, String request) throws IOException;
/*
* FIXME We will need to remove the IOException declaration because
* this type of error is linked to the proxy type. A wrapper
* class was created, but some proxies out there (MondrianInprocProxy...)
* still uses this.
*/
byte[] get(URL url, String request) throws XmlaOlap4jProxyException,IOException;

/**
* Submits a request for background execution.
Expand Down
25 changes: 25 additions & 0 deletions src/org/olap4j/driver/xmla/proxy/XmlaOlap4jProxyException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
// $Id:$
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2007-2007 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package org.olap4j.driver.xmla.proxy;

/**
* Gets thrown whenever an exception is encountered during the querying
* of an XmlaOlap4jProxy subclass.
*
* @author Luc Boudreau
* @version $Id:$
*/
public class XmlaOlap4jProxyException extends Exception {
private static final long serialVersionUID = 1729906649527317997L;
public XmlaOlap4jProxyException(String message, Throwable cause) {
super(message, cause);
}
}
//End XmlaOlap4jProxyException.java

0 comments on commit 19f9d9d

Please sign in to comment.