Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
337 changes: 317 additions & 20 deletions src/main/java/mondrian/xmla/RowsetDefinition.java

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/main/java/mondrian/xmla/XmlaConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public interface XmlaConstants {
public static final String NS_SQL = "urn:schemas-microsoft-com:xml-sql";
public static final String NS_XMLA_EX =
"urn:schemas-microsoft-com:xml-analysis:exception";
public static final String NS_XMLA_MS_EXTENSIONS =
"http://schemas.microsoft.com/analysisservices/2003/engine";

public static final String NS_SOAP_SECEXT =
"http://schemas.xmlsoap.org/ws/2002/04/secext";
Expand Down
43 changes: 42 additions & 1 deletion src/main/java/mondrian/xmla/XmlaHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,10 @@ private void execute(
XmlaResponse response)
throws XmlaException
{
if (request.isCancel()) {
cancelSession(request);
return;
}
final Map<String, String> properties = request.getProperties();

// Default responseMimeType is SOAP.
Expand Down Expand Up @@ -1318,6 +1322,32 @@ static void writeEmptyDatasetXmlSchema(SaxWriter writer, SetType setType) {
writer.endElement(); // xsd:schema
}

private void cancelSession(XmlaRequest request) throws XmlaException {
String sessionId = request.getStatement();
if (!authorizeSessionCancel(sessionId, request)) {
throw new XmlaException(
CLIENT_FAULT_FC,
CHH_AUTHORIZATION_CODE,
CHH_AUTHORIZATION_FAULT_FS,
Util.newInternal(
"Unauthorized request to cancel session " + sessionId));
}
XmlaSessionManager.getInstance().cancelSession(sessionId);
}

protected boolean authorizeSessionCancel(
String sessionId,
XmlaRequest request)
{
String[] credentials =
XmlaSessionManager.getInstance().getSessionCredentials(sessionId);
if (credentials == null || credentials.length == 0 || credentials[0] == null) {
return true;
}
return credentials[0].equals(request.getUsername()) && (
credentials[1] == null || credentials[1].equals(request.getPassword()));
}

private QueryResult executeDrillThroughQuery(XmlaRequest request)
throws XmlaException
{
Expand All @@ -1336,16 +1366,19 @@ private QueryResult executeDrillThroughQuery(XmlaRequest request)
OlapStatement statement = null;
ResultSet resultSet = null;
try {
String mdx = request.getStatement();
connection =
getConnection(request, Collections.<String, String>emptyMap());
statement = connection.createStatement();
XmlaSessionManager.getInstance().addStatementToSession(
request.getSessionId(), statement, mdx);
final XmlaHandler.XmlaExtra extra = connectionFactory.getExtra();
final boolean enableRowCount = extra.isTotalCountEnabled();
final int[] rowCountSlot = enableRowCount ? new int[]{0} : null;
resultSet =
extra.executeDrillthrough(
statement,
request.getStatement(),
mdx,
advanced,
tabFields,
rowCountSlot);
Expand Down Expand Up @@ -1375,6 +1408,8 @@ private QueryResult executeDrillThroughQuery(XmlaRequest request)
}
}
if (statement != null) {
XmlaSessionManager.getInstance().removeStatementFromSession(
request.getSessionId(), statement);
try {
statement.close();
} catch (SQLException e) {
Expand Down Expand Up @@ -1658,6 +1693,8 @@ private QueryResult executeQuery(XmlaRequest request)
extra.setPreferList(connection);
try {
statement = connection.prepareOlapStatement(mdx);
XmlaSessionManager.getInstance().addStatementToSession(
request.getSessionId(), statement, mdx);
} catch (XmlaException ex) {
throw ex;
} catch (Exception ex) {
Expand Down Expand Up @@ -1699,6 +1736,10 @@ private QueryResult executeQuery(XmlaRequest request)
ex);
}
} finally {
if (statement != null) {
XmlaSessionManager.getInstance().removeStatementFromSession(
request.getSessionId(), statement);
}
if (!success) {
if (cellSet != null) {
try {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/mondrian/xmla/XmlaRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public interface XmlaRequest {
*/
boolean isDrillThrough();

/**
* Indicate whether EXECUTE method is a session cancel.
*/
boolean isCancel();

/**
* The username to use to open the underlying olap4j connection.
* Can be null.
Expand Down
42 changes: 41 additions & 1 deletion src/main/java/mondrian/xmla/XmlaServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.*;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
Expand All @@ -38,9 +39,11 @@ public abstract class XmlaServlet
"OptionalDataSourceConfig";
public static final String PARAM_CHAR_ENCODING = "CharacterEncoding";
public static final String PARAM_CALLBACKS = "Callbacks";
public static final String PARAM_CANCEL_SQL_STATE = "CancelSqlState";

protected XmlaHandler xmlaHandler = null;
protected String charEncoding = null;
protected final HashSet<String> cancelSqlStateSet = new HashSet<String>();
private final List<XmlaRequestCallback> callbackList =
new ArrayList<XmlaRequestCallback>();

Expand Down Expand Up @@ -95,6 +98,8 @@ public void init(ServletConfig servletConfig)
// init: callbacks
initCallbacks(servletConfig);

initCancelSqlState(servletConfig);

this.connectionFactory = createConnectionFactory(servletConfig);
}

Expand Down Expand Up @@ -133,6 +138,21 @@ protected final List<XmlaRequestCallback> getCallbacks() {
return Collections.unmodifiableList(callbackList);
}

private boolean isCancelException(Throwable t) {
if (cancelSqlStateSet == null || cancelSqlStateSet.isEmpty()) {
return false;
}

if (t instanceof SQLException) {
String sqlState = ((SQLException) t).getSQLState();
return cancelSqlStateSet.contains(sqlState);
} else if (t.getCause() != null) {
return isCancelException(t.getCause());
} else {
return false;
}
}

/**
* Main entry for HTTP post method
*
Expand Down Expand Up @@ -320,7 +340,11 @@ protected void doPost(
responseSoapParts,
context);
} catch (XmlaException xex) {
LOGGER.error("Errors when handling XML/A message", xex);
if (isCancelException(xex)) {
LOGGER.info("XML/A request canceled", xex);
} else {
LOGGER.error("Errors when handling XML/A message", xex);
}
handleFault(response, responseSoapParts, phase, xex);
phase = Phase.SEND_ERROR;
marshallSoapMessage(response, responseSoapParts, mimeType);
Expand Down Expand Up @@ -441,6 +465,22 @@ protected void initCharEncodingHandler(ServletConfig servletConfig) {
}
}

/**
* Initialize possible cancel sql states
*/
protected void initCancelSqlState(ServletConfig servletConfig) {
String paramValue = servletConfig.getInitParameter(
PARAM_CANCEL_SQL_STATE);
if (paramValue != null) {
for (String sqlState : paramValue.split(",")) {
sqlState = sqlState.trim();
if (sqlState.length() > 0) {
cancelSqlStateSet.add(sqlState);
}
}
}
}

/**
* Registers callbacks configured in web.xml.
*/
Expand Down
Loading