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

smolok.service.binding.camel.CamelOperationBindingFactory.groovy Maven / Gradle / Ivy

There is a newer version: 0.0.11
Show newest version
package smolok.service.binding.camel

import org.apache.camel.spi.Registry
import org.apache.commons.lang3.Validate
import smolok.service.binding.Credentials
import smolok.service.binding.OperationBinding
import smolok.service.binding.OperationBindingFactory
import smolok.service.binding.Tenant

import java.lang.reflect.Method

import static java.util.Arrays.asList
import static org.slf4j.LoggerFactory.getLogger

class CamelOperationBindingFactory implements OperationBindingFactory {

    // Logger

    private static final LOG = getLogger(CamelOperationBindingFactory.class)

    private final Registry registry

    CamelOperationBindingFactory(Registry registry) {
        this.registry = registry
    }

    @Override
    OperationBinding operationBinding(Credentials credentials, String channel, Object incomingPayload, Map headers) {
        LOG.debug('Parsing operation binding for channel: {}', channel)
        def normalizedChannel = channel.substring(channel.lastIndexOf('/') + 1)
        LOG.debug('Channel {} after normalization: {}', channel, normalizedChannel)

        String[] channelParts = normalizedChannel.split("\\.");
        String service = channelParts[0];
        String operation = channelParts[1];

        def bean = registry.lookupByName(service)
        Validate.notNull(bean, "Cannot find service with name '%s'.", service);
        Class beanType = bean.getClass();

        LOG.debug("Detected service bean type {} for operation: {}", beanType, operation);
        List beanMethods = new ArrayList<>(asList(beanType.getDeclaredMethods()));
        beanMethods.addAll(asList(beanType.getMethods()));
        Method operationMethod = beanMethods.find{method -> method.getName().equals(operation)}

        List arguments = new LinkedList<>(asList(channelParts).subList(2, channelParts.length))

        for(Map.Entry header : headers.entrySet()) {
            if(header.getKey().startsWith("SMOLOK_ARG")) {
                arguments.add(header.getValue());
            }
        }

        if (incomingPayload != null) {
            Object payload = incomingPayload;
            arguments.add(payload);
        }

        def tenantPosition = operationMethod.parameterAnnotations.findIndexOf {
            it.find{ it.annotationType() == Tenant.class }
        }
        if(tenantPosition >= 0) {
            arguments.addAll(tenantPosition, credentials.tenant())
        }

        new OperationBinding(service, operationMethod, arguments)
    }

}