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

ru.yandex.qatools.camelot.common.AggregatorPluginAnnotatedMethodInvoker Maven / Gradle / Ivy

There is a newer version: 2.5.4
Show newest version
package ru.yandex.qatools.camelot.common;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.spi.AggregationRepository;
import ru.yandex.qatools.camelot.api.error.RepositoryDirtyWriteAttemptException;
import ru.yandex.qatools.camelot.api.error.RepositoryLockWaitException;
import ru.yandex.qatools.camelot.api.error.RepositoryUnreachableException;
import ru.yandex.qatools.camelot.config.Plugin;
import ru.yandex.qatools.camelot.config.PluginContext;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;

import static org.apache.commons.lang3.ArrayUtils.addAll;

/**
 * @author Ilya Sadykov (mailto: [email protected])
 * @author Innokenty Shuvalov (mailto: [email protected])
 */
public class AggregatorPluginAnnotatedMethodInvoker extends PluginAnnotatedMethodInvoker {
    final CamelContext camelContext;
    final boolean readOnly;
    private Object pluginInstance;

    public AggregatorPluginAnnotatedMethodInvoker(CamelContext camelContext, Plugin plugin,
                                                  Class anClass, boolean readOnly)
            throws ReflectiveOperationException {
        super(plugin, anClass);
        this.camelContext = camelContext;
        this.readOnly = readOnly;
    }

    public void setPluginInstance(Object pluginInstance) {
        this.pluginInstance = pluginInstance;
    }

    @Override
    public void invoke(Method method, Object... args) {
        final AggregationRepository repo = plugin.getContext().getAggregationRepo();
        final Set keys = repo.getKeys();

        LOGGER.debug("Invoking method {} of plugin {}, repo class {}",
                method.getName(), plugin.getId(), repo.getClass().getName());

        for (String key : keys) {
            invokeForKey(repo, key, method, args);
        }
    }

    private void invokeForKey(AggregationRepository repo, String key, Method method, Object[] args) {
        try {
            invokeForKeyOrDie(repo, key, method, args);
        } catch (RepositoryLockWaitException e) { //NOSONAR
            LOGGER.warn("Failed to process the plugin's '{}' method '{}' invocation: {}!",
                    plugin.getId(), method.getName(), e.getMessage());
            repo.confirm(camelContext, key);
        } catch (RepositoryUnreachableException | RepositoryDirtyWriteAttemptException e) { //NOSONAR
            LOGGER.warn("Failed to process the plugin's '{}' method '{}' invocation: {}!",
                    plugin.getId(), method.getName(), e.getMessage());
        } catch (InvocationTargetException e) { //NOSONAR
            LOGGER.error("Failed to process the plugin's '{}' method '{}' invocation!",
                    plugin.getId(), method.getName(), e.getTargetException());
        } catch (Exception e) {
            LOGGER.error("Failed to process the plugin's '{}' method '{}' invocation!",
                    plugin.getId(), method.getName(), e);
        } finally {
            unlockQuietly(repo, key);
        }
    }

    private void invokeForKeyOrDie(AggregationRepository repo, String key, Method method, Object[] args) throws Exception { //NOSONAR
        LOGGER.debug("Trying to invoke aggregator's method '{}' for key '{}' of plugin {}",
                method.getName(), key, plugin.getId());

        Exchange exchange = getExchange(repo, key);
        if (exchange != null) {
            invokeForExchange(key, exchange, method, args);
            if (!readOnly) {
                repo.add(camelContext, key, exchange);
            }
        } else {
            LOGGER.warn("Exchange is already null for plugin {} and key {}", plugin.getId(), key);
        }
    }

    private Exchange getExchange(AggregationRepository repo, String key) {
        Exchange exchange;
        if (readOnly && repo instanceof AggregationRepositoryWithLocks) {
            exchange = ((AggregationRepositoryWithLocks) repo).getWithoutLock(camelContext, key);
        } else {
            exchange = repo.get(camelContext, key);
        }
        return exchange;
    }

    @SuppressWarnings("unchecked")
    private void invokeForExchange(String key, Exchange exchange, Method method, Object[] args) throws Exception { //NOSONAR
        final PluginContext context = plugin.getContext();
        final ClassLoader classLoader = context.getClassLoader();
        Object aggregator = (pluginInstance == null) ?
                            classLoader.loadClass(plugin.getAggregator()).newInstance() :
                            pluginInstance;
        context.getInjector().inject(aggregator, context, exchange);

        context.getMessagesSerializer().preProcess(exchange, classLoader);
        Object body = exchange.getIn().getBody();
        Object[] mArgs = new Object[]{body};
        if (method.getParameterTypes().length > 1) {
            mArgs = addAll(mArgs, args);
        }

        LOGGER.debug("Invoking '{}' for key '{}' of plugin {}...",
                method.getName(), key, plugin.getId());
        method.invoke(aggregator, mArgs);
        LOGGER.debug("Invocation of '{}' for key '{}' of plugin {} done successfully",
                method.getName(), key, plugin.getId());
        context.getMessagesSerializer().postProcess(exchange, classLoader);
    }

    private void unlockQuietly(AggregationRepository repo, String key) {
        if (!readOnly && repo instanceof AggregationRepositoryWithLocks) {
            ((AggregationRepositoryWithLocks) repo).unlockQuietly(key);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy