Skip to content

Commit

Permalink
TEIID-2906 adding an option to sanitize messages
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins authored and johnathonlee committed May 2, 2014
1 parent 7b29892 commit 73c1fe6
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 7 deletions.
55 changes: 55 additions & 0 deletions client/src/main/java/org/teiid/client/util/ExceptionUtil.java
Expand Up @@ -22,10 +22,12 @@

package org.teiid.client.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import org.teiid.client.xa.XATransactionException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidException;
import org.teiid.core.TeiidRuntimeException;


Expand Down Expand Up @@ -66,4 +68,57 @@ public static Throwable convertException(Method method, Throwable exception) {
}
return new TeiidRuntimeException(exception);
}

/**
* Strip out the message and optionally the stacktrace
* @param t
* @return
*/
public static Throwable sanitize(Throwable t, boolean perserveStack) {
String code = null;
if (t instanceof TeiidException) {
code = ((TeiidException)t).getCode();
} else if (t instanceof TeiidRuntimeException) {
code = ((TeiidRuntimeException)t).getCode();
} else {
code = t.getClass().getName();
}
Throwable child = null;
if (t.getCause() != null && t.getCause() != t) {
child = sanitize(t.getCause(), perserveStack);
}
Class<?> clazz = t.getClass();
Throwable result = null;
while (clazz != null) {
if (clazz == Throwable.class || clazz == Exception.class) {
break;
}
Constructor<?> ctor = null;
try {
ctor = clazz.getDeclaredConstructor(new Class<?>[] {String.class});
result = (Throwable) ctor.newInstance(code);
break;
} catch (Exception e) {

}
clazz = clazz.getSuperclass();
}
if (result == null) {
result = new TeiidException(code);
}
if (result instanceof TeiidException) {
((TeiidException)result).setCode(code);
} else if (result instanceof TeiidRuntimeException) {
((TeiidException)result).setCode(code);
}
if (child != null) {
result.initCause(child);
}
if (perserveStack) {
result.setStackTrace(t.getStackTrace());
} else {
result.setStackTrace(new StackTraceElement[0]);
}
return result;
}
}
49 changes: 49 additions & 0 deletions client/src/test/java/org/teiid/client/util/TestExceptionUtil.java
@@ -0,0 +1,49 @@
/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/

package org.teiid.client.util;

import static org.junit.Assert.*;

import org.junit.Test;
import org.teiid.core.TeiidException;
import org.teiid.jdbc.JDBCPlugin;

@SuppressWarnings("nls")
public class TestExceptionUtil {

@Test public void testSanitize() {
TeiidException te = new TeiidException(JDBCPlugin.Event.TEIID20000, "you don't want to see this");
te.initCause(new Exception("or this"));

Throwable t = ExceptionUtil.sanitize(te, true);
assertTrue(t.getStackTrace().length != 0);
assertNotNull(t.getCause());
assertEquals("TEIID20000", t.getMessage());
assertEquals("java.lang.Exception", t.getCause().getMessage());

t = ExceptionUtil.sanitize(te, false);
assertEquals(0, t.getStackTrace().length);
assertEquals("TEIID20000", t.getMessage());
}

}
Expand Up @@ -38,6 +38,7 @@

import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.client.ResizingArrayList;
import org.teiid.client.util.ExceptionUtil;
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.FileStore;
import org.teiid.common.buffer.FileStoreInputStreamFactory;
Expand All @@ -63,6 +64,7 @@
import org.teiid.logging.CommandLogMessage.Event;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.source.XMLSystemFunctions;
import org.teiid.query.metadata.QueryMetadataInterface;
Expand Down Expand Up @@ -243,11 +245,17 @@ private TranslatorException handleError(Throwable t) {
String msg = QueryPlugin.Util.getString("ConnectorWorker.process_failed", this.id); //$NON-NLS-1$
if (isCancelled.get()) {
LogManager.logDetail(LogConstants.CTX_CONNECTOR, msg);
} else if (t instanceof TranslatorException || t instanceof TeiidProcessingException) {
LogManager.logWarning(LogConstants.CTX_CONNECTOR, t, msg);
} else {
LogManager.logError(LogConstants.CTX_CONNECTOR, t, msg);
}
Throwable toLog = t;
if (this.requestMsg.getCommandContext().getOptions().isSanitizeMessages() && !LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR, MessageLevel.DETAIL)) {
toLog = ExceptionUtil.sanitize(toLog, true);
}
if (toLog instanceof TranslatorException || toLog instanceof TeiidProcessingException) {
LogManager.logWarning(LogConstants.CTX_CONNECTOR, toLog, msg);
} else {
LogManager.logError(LogConstants.CTX_CONNECTOR, toLog, msg);
}
}
if (t instanceof TranslatorException) {
return (TranslatorException)t;
}
Expand Down
Expand Up @@ -129,7 +129,7 @@ public class Request {
private int userRequestConcurrency;
private AuthorizationValidator authorizationValidator;
private Executor executor;
private Options options;
protected Options options;

void initialize(RequestMessage requestMsg,
BufferManager bufferManager,
Expand Down
Expand Up @@ -41,6 +41,7 @@
import org.teiid.client.ResultsMessage;
import org.teiid.client.lob.LobChunk;
import org.teiid.client.metadata.ParameterInfo;
import org.teiid.client.util.ExceptionUtil;
import org.teiid.client.util.ResultsReceiver;
import org.teiid.client.xa.XATransactionException;
import org.teiid.common.buffer.BlockedException;
Expand Down Expand Up @@ -83,6 +84,7 @@
import org.teiid.query.sql.symbol.Symbol;
import org.teiid.query.util.CommandContext;
import org.teiid.query.util.GeneratedKeysImpl;
import org.teiid.query.util.Options;

public class RequestWorkItem extends AbstractWorkItem implements PrioritizedRunnable {

Expand Down Expand Up @@ -160,6 +162,7 @@ private enum TransactionState {NONE, ACTIVE, DONE}
final RequestMessage requestMsg;
final RequestID requestID;
private Request request; //provides the processing plan, held on a temporary basis
private Options options;
private final int processorTimeslice;
private CacheID cid;
private final TransactionService transactionService;
Expand Down Expand Up @@ -213,6 +216,9 @@ public RequestWorkItem(DQPCore dqpCore, RequestMessage requestMsg, Request reque
this.transactionService = dqpCore.getTransactionService();
this.dqpCore = dqpCore;
this.request = request;
if (request != null) {
this.options = request.options;
}
this.dqpWorkContext = workContext;
this.requestResults(1, requestMsg.getFetchSize(), receiver);
}
Expand Down Expand Up @@ -359,6 +365,9 @@ private void handleThrowable(Throwable e) {
//Case 5558: Differentiate between system level errors and
//processing errors. Only log system level errors as errors,
//log the processing errors as warnings only
if (this.options.isSanitizeMessages() && !LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
e = ExceptionUtil.sanitize(e, true);
}
if(e instanceof TeiidProcessingException) {
Throwable cause = e;
while (cause.getCause() != null && cause.getCause() != cause) {
Expand Down Expand Up @@ -892,12 +901,20 @@ protected boolean sendResultsIfNeeded(TupleBatch batch) throws TeiidComponentExc
}

private void setWarnings(ResultsMessage response) {
boolean sanitize = this.options.isSanitizeMessages() && !LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL);

// send any warnings with the response object
List<Throwable> responseWarnings = new ArrayList<Throwable>();
if (this.processor != null) {
List<Exception> currentWarnings = processor.getAndClearWarnings();
if (currentWarnings != null) {
responseWarnings.addAll(currentWarnings);
if (sanitize) {
for (Exception e : currentWarnings) {
responseWarnings.add(ExceptionUtil.sanitize(e, false));
}
} else {
responseWarnings.addAll(currentWarnings);
}
}
}
response.setWarnings(responseWarnings);
Expand Down Expand Up @@ -950,6 +967,10 @@ private void sendError() {
LogManager.logDetail(LogConstants.CTX_DQP, processingException, "Sending error to client", requestID); //$NON-NLS-1$
ResultsMessage response = new ResultsMessage();
Throwable exception = this.processingException;
if (this.options.isSanitizeMessages() && !LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
//we still convey an exception hierarcy here because the client logic looks for certian exception types
exception = ExceptionUtil.sanitize(exception, false);
}
if (isCanceled) {
exception = addCancelCode(exception);
}
Expand Down
Expand Up @@ -55,6 +55,7 @@
import org.teiid.dqp.service.TransactionService;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
Expand Down Expand Up @@ -877,7 +878,9 @@ public void addWarning(Exception warning) {
}
globalState.warnings.add(warning);
}
LogManager.logInfo(LogConstants.CTX_DQP, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31105, warning.getMessage()));
if (!this.getOptions().isSanitizeMessages() || LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
LogManager.logInfo(LogConstants.CTX_DQP, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31105, warning.getMessage()));
}
}

public TupleSourceCache getTupleSourceCache() {
Expand Down
15 changes: 15 additions & 0 deletions engine/src/main/java/org/teiid/query/util/Options.java
Expand Up @@ -33,12 +33,14 @@ public class Options {
public static final String PUSHDOWN_DEFAULT_NULL_ORDER = "org.teiid.pushdownDefaultNullOrder"; //$NON-NLS-1$
public static final String IMPLICIT_MULTISOURCE_JOIN = "org.teiid.implicitMultiSourceJoin"; //$NON-NLS-1$
public static final String JOIN_PREFETCH_BATCHES = "org.teiid.joinPrefetchBatches"; //$NON-NLS-1$
public static final String SANITIZE_MESSAGES = "org.teiid.sanitizeMessages"; //$NON-NLS-1$

private Properties properties;
private boolean subqueryUnnestDefault;
private boolean pushdownDefaultNullOrder;
private boolean implicitMultiSourceJoin = true;
private int joinPrefetchBatches = 10;
private boolean sanitizeMessages;

public Properties getProperties() {
return properties;
Expand Down Expand Up @@ -99,5 +101,18 @@ public Options joinPrefetchBatches(int i) {
this.joinPrefetchBatches = i;
return this;
}

public void setSanitizeMessages(boolean sanitizeMessages) {
this.sanitizeMessages = sanitizeMessages;
}

public boolean isSanitizeMessages() {
return sanitizeMessages;
}

public Options sanitizeMessages(boolean b) {
this.sanitizeMessages = b;
return this;
}

}

0 comments on commit 73c1fe6

Please sign in to comment.