From 8ce6c7ee3ef5f65424aebd788ae2f96af1d68d2d Mon Sep 17 00:00:00 2001 From: buczekp <buczekp> Date: Tue, 12 Jul 2011 11:42:34 +0000 Subject: [PATCH] [LMS-2368] introduced AOP advisor for translation of TransactionExceptions on server level SVN: 22086 --- ...entServiceExceptionTranslatingAdvisor.java | 18 +--- .../ServerExceptionTranslatingAdvisor.java | 85 +++++++++++++++++++ .../source/java/genericApplicationContext.xml | 6 ++ 3 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServerExceptionTranslatingAdvisor.java diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ClientServiceExceptionTranslatingAdvisor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ClientServiceExceptionTranslatingAdvisor.java index a154f89a5d8..828b1e393d2 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ClientServiceExceptionTranslatingAdvisor.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ClientServiceExceptionTranslatingAdvisor.java @@ -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()); - } - } } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServerExceptionTranslatingAdvisor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServerExceptionTranslatingAdvisor.java new file mode 100644 index 00000000000..870c819d29a --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServerExceptionTranslatingAdvisor.java @@ -0,0 +1,85 @@ +/* + * 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()); + } + } + } + +} diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml index 3558d0caa19..672df3f4730 100644 --- a/openbis/source/java/genericApplicationContext.xml +++ b/openbis/source/java/genericApplicationContext.xml @@ -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" /> <!-- -- GitLab