Skip to content
Snippets Groups Projects
Commit 8ce6c7ee authored by buczekp's avatar buczekp
Browse files

[LMS-2368] introduced AOP advisor for translation of TransactionExceptions on server level

SVN: 22086
parent 3103300c
No related branches found
No related tags found
No related merge requests found
......@@ -23,9 +23,7 @@ import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.RootClassFilter;
import org.springframework.transaction.TransactionSystemException;
import ch.systemsx.cisd.common.exceptions.UserFailureException;
import ch.systemsx.cisd.openbis.generic.client.web.client.IClientService;
import ch.systemsx.cisd.openbis.generic.client.web.server.translator.UserFailureExceptionTranslator;
......@@ -67,26 +65,12 @@ public class ClientServiceExceptionTranslatingAdvisor extends DefaultPointcutAdv
{
try
{
return proceedWithTransactionSystemExceptionTranslation(invocation);
return invocation.proceed();
} catch (ch.systemsx.cisd.common.exceptions.UserFailureException ex)
{
throw UserFailureExceptionTranslator.translate(ex);
}
}
private Object proceedWithTransactionSystemExceptionTranslation(MethodInvocation invocation)
throws Throwable
{
try
{
return invocation.proceed();
} catch (TransactionSystemException e)
{
// Deferred trigger may throw an exception just before commit.
// Message in the exception is readable for the user.
throw new UserFailureException(e.getMostSpecificCause().getMessage());
}
}
}
}
/*
* Copyright 2011 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.generic.server;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.RootClassFilter;
import org.springframework.core.NestedRuntimeException;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.annotation.Transactional;
import ch.systemsx.cisd.common.exceptions.UserFailureException;
import ch.systemsx.cisd.openbis.generic.shared.IServer;
/**
* Translates deeply nested exceptions thrown on server side e.g. by Spring (like
* {@link TransactionSystemException}) into {UserFailureException} with message taken from the root
* exception cause.
* <p>
* The most important reason why this advisor was introduced was to translate exceptions that happen
* just before commit/rollback of transactions, like {@link TransactionSystemException}. Such
* exceptions can't be handled inside the server methods because the commit/rollback is invoked
* outside the server class by Spring AOP (see {@link Transactional}). Without this advisor the
* translation would need to be done in all clients - web, command line, APIs.
*
* @author Piotr Buczek
*/
public class ServerExceptionTranslatingAdvisor extends DefaultPointcutAdvisor
{
private static final long serialVersionUID = 1L;
public ServerExceptionTranslatingAdvisor()
{
super(new AllServerMethodsPointcut(), new UserFailureExceptionTranslatingInterceptor());
}
private static class AllServerMethodsPointcut implements Pointcut
{
public MethodMatcher getMethodMatcher()
{
return MethodMatcher.TRUE;
}
public ClassFilter getClassFilter()
{
return new RootClassFilter(IServer.class);
}
}
private static class UserFailureExceptionTranslatingInterceptor implements MethodInterceptor
{
public Object invoke(MethodInvocation invocation) throws Throwable
{
try
{
return invocation.proceed();
} catch (NestedRuntimeException e) // e.g. TransactionSystemException
{
// Deferred trigger may throw an exception just before commit.
// Message in the exception is readable for the user.
throw new UserFailureException(e.getMostSpecificCause().getMessage());
}
}
}
}
......@@ -113,6 +113,12 @@
-->
<bean id="html-escaping-advisor" class="ch.systemsx.cisd.openbis.generic.client.web.server.StringHtmlEscapingPointcutAdvisor" />
<!--
// Exception translation
-->
<bean id="client-service-exception-translating-advisor" class="ch.systemsx.cisd.openbis.generic.client.web.server.ClientServiceExceptionTranslatingAdvisor" />
<bean id="server-exception-translating-advisor" class="ch.systemsx.cisd.openbis.generic.server.ServerExceptionTranslatingAdvisor" />
<bean id="rpc-name-server" class="ch.systemsx.cisd.common.api.server.RpcServiceNameServer" />
<!--
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment