All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.jsonrpc.impl.TransactionProxy Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2019 Lumina Networks, Inc. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.jsonrpc.impl;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Set;
import org.opendaylight.jsonrpc.model.JsonRpcTransactionFacade;
import org.opendaylight.mdsal.common.api.ReadFailedException;
import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Proxy that correctly propagates cause so that meaningful response can be generated by RESTConf.
 *
 * @author Richard Kosegi
 * @since Jul 26, 2019
 */
public final class TransactionProxy implements InvocationHandler {
    private static final Logger LOG = LoggerFactory.getLogger(TransactionProxy.class);
    private static final Set READ_METHODS = ImmutableSet.of("read", "exists");
    private final JsonRpcTransactionFacade delegate;

    private TransactionProxy(JsonRpcTransactionFacade delegate) {
        this.delegate = delegate;
    }

    /**
     * Create new proxy instance using given delegate.
     *
     * @param delegate target instance to whom calls are intercepted
     * @return new proxy instance
     */
    public static JsonRpcTransactionFacade create(JsonRpcTransactionFacade delegate) {
        return (JsonRpcTransactionFacade) Proxy.newProxyInstance(JsonRpcTransactionFacade.class.getClassLoader(),
                new Class[] { JsonRpcTransactionFacade.class }, new TransactionProxy(delegate));
    }

    @SuppressWarnings("checkstyle:IllegalCatch")
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            return method.invoke(delegate, args);
        } catch (Exception e) {
            final Throwable rootCause = Throwables.getRootCause(e);
            //only debug level, upper layer (restconf) already log same stacktrace on WARN level
            LOG.debug("Caught exception while invoking method '{}', propagating it to caller", method.getName(),
                    rootCause);
            if (READ_METHODS.contains(method.getName())) {
                return FluentFutures.immediateFailedFluentFuture(
                        new ReadFailedException("Invocation of method '" + method.getName() + "' failed", rootCause));
            } else if ("commit".equals(method.getName())) {
                return FluentFutures.immediateFailedFluentFuture(
                        new TransactionCommitFailedException("Commit of transaction failed", rootCause));
            } else {
                //this will be shown as HTTP500 in restconf, but there is nothing more we can do about it
                throw new IllegalStateException("Operation '" + method.getName() + "' failed", rootCause);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy