Search in sources :

Example 1 with Gateway

use of org.springframework.integration.annotation.Gateway in project spring-integration by spring-projects.

the class GatewayProxyFactoryBean method createGatewayForMethod.

private MethodInvocationGateway createGatewayForMethod(Method method) {
    Gateway gatewayAnnotation = method.getAnnotation(Gateway.class);
    String requestChannelName = null;
    String replyChannelName = null;
    Expression requestTimeout = this.defaultRequestTimeout;
    Expression replyTimeout = this.defaultReplyTimeout;
    String payloadExpression = this.globalMethodMetadata != null ? this.globalMethodMetadata.getPayloadExpression() : null;
    Map<String, Expression> headerExpressions = new HashMap<String, Expression>();
    if (gatewayAnnotation != null) {
        requestChannelName = gatewayAnnotation.requestChannel();
        replyChannelName = gatewayAnnotation.replyChannel();
        /*
			 * INT-2636 Unspecified annotation attributes should not
			 * override the default values supplied by explicit configuration.
			 * There is a small risk that someone has used Long.MIN_VALUE explicitly
			 * to indicate an indefinite timeout on a gateway method and that will
			 * no longer work as expected; they will need to use, say, -1 instead.
			 */
        if (requestTimeout == null || gatewayAnnotation.requestTimeout() != Long.MIN_VALUE) {
            requestTimeout = new ValueExpression<>(gatewayAnnotation.requestTimeout());
        }
        if (StringUtils.hasText(gatewayAnnotation.requestTimeoutExpression())) {
            requestTimeout = ExpressionUtils.longExpression(gatewayAnnotation.requestTimeoutExpression());
        }
        if (replyTimeout == null || gatewayAnnotation.replyTimeout() != Long.MIN_VALUE) {
            replyTimeout = new ValueExpression<>(gatewayAnnotation.replyTimeout());
        }
        if (StringUtils.hasText(gatewayAnnotation.replyTimeoutExpression())) {
            replyTimeout = ExpressionUtils.longExpression(gatewayAnnotation.replyTimeoutExpression());
        }
        if (payloadExpression == null || StringUtils.hasText(gatewayAnnotation.payloadExpression())) {
            payloadExpression = gatewayAnnotation.payloadExpression();
        }
        if (!ObjectUtils.isEmpty(gatewayAnnotation.headers())) {
            for (GatewayHeader gatewayHeader : gatewayAnnotation.headers()) {
                String value = gatewayHeader.value();
                String expression = gatewayHeader.expression();
                String name = gatewayHeader.name();
                boolean hasValue = StringUtils.hasText(value);
                if (hasValue == StringUtils.hasText(expression)) {
                    throw new BeanDefinitionStoreException("exactly one of 'value' or 'expression' " + "is required on a gateway's header.");
                }
                headerExpressions.put(name, hasValue ? new LiteralExpression(value) : EXPRESSION_PARSER.parseExpression(expression));
            }
        }
    } else if (this.methodMetadataMap != null && this.methodMetadataMap.size() > 0) {
        GatewayMethodMetadata methodMetadata = this.methodMetadataMap.get(method.getName());
        if (methodMetadata != null) {
            if (StringUtils.hasText(methodMetadata.getPayloadExpression())) {
                payloadExpression = methodMetadata.getPayloadExpression();
            }
            if (!CollectionUtils.isEmpty(methodMetadata.getHeaderExpressions())) {
                headerExpressions.putAll(methodMetadata.getHeaderExpressions());
            }
            requestChannelName = methodMetadata.getRequestChannelName();
            replyChannelName = methodMetadata.getReplyChannelName();
            String reqTimeout = methodMetadata.getRequestTimeout();
            if (StringUtils.hasText(reqTimeout)) {
                requestTimeout = ExpressionUtils.longExpression(reqTimeout);
            }
            String repTimeout = methodMetadata.getReplyTimeout();
            if (StringUtils.hasText(repTimeout)) {
                replyTimeout = ExpressionUtils.longExpression(repTimeout);
            }
        }
    }
    Map<String, Object> headers = null;
    // We don't want to eagerly resolve the error channel here
    Object errorChannel = this.errorChannel == null ? this.errorChannelName : this.errorChannel;
    if (errorChannel != null && method.getReturnType().equals(void.class)) {
        headers = new HashMap<>();
        headers.put(MessageHeaders.ERROR_CHANNEL, errorChannel);
    }
    if (getMessageBuilderFactory() instanceof DefaultMessageBuilderFactory) {
        Set<String> headerNames = new HashSet<>(headerExpressions.keySet());
        if (this.globalMethodMetadata != null) {
            headerNames.addAll(this.globalMethodMetadata.getHeaderExpressions().keySet());
        }
        List<MethodParameter> methodParameters = GatewayMethodInboundMessageMapper.getMethodParameterList(method);
        for (MethodParameter methodParameter : methodParameters) {
            Header header = methodParameter.getParameterAnnotation(Header.class);
            if (header != null) {
                String headerName = GatewayMethodInboundMessageMapper.determineHeaderName(header, methodParameter);
                headerNames.add(headerName);
            }
        }
        for (String header : headerNames) {
            if ((MessageHeaders.ID.equals(header) || MessageHeaders.TIMESTAMP.equals(header))) {
                throw new BeanInitializationException("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers.\n" + "Wrong headers configuration for " + getComponentName());
            }
        }
    }
    GatewayMethodInboundMessageMapper messageMapper = new GatewayMethodInboundMessageMapper(method, headerExpressions, this.globalMethodMetadata != null ? this.globalMethodMetadata.getHeaderExpressions() : null, headers, this.argsMapper, this.getMessageBuilderFactory());
    if (StringUtils.hasText(payloadExpression)) {
        messageMapper.setPayloadExpression(payloadExpression);
    }
    messageMapper.setBeanFactory(getBeanFactory());
    MethodInvocationGateway gateway = new MethodInvocationGateway(messageMapper);
    if (this.errorChannel != null) {
        gateway.setErrorChannel(this.errorChannel);
    } else if (StringUtils.hasText(this.errorChannelName)) {
        gateway.setErrorChannelName(this.errorChannelName);
    }
    if (this.getTaskScheduler() != null) {
        gateway.setTaskScheduler(this.getTaskScheduler());
    }
    gateway.setBeanName(this.getComponentName());
    if (StringUtils.hasText(requestChannelName)) {
        gateway.setRequestChannelName(requestChannelName);
    } else if (StringUtils.hasText(this.defaultRequestChannelName)) {
        gateway.setRequestChannelName(this.defaultRequestChannelName);
    } else {
        gateway.setRequestChannel(this.defaultRequestChannel);
    }
    if (StringUtils.hasText(replyChannelName)) {
        gateway.setReplyChannelName(replyChannelName);
    } else if (StringUtils.hasText(this.defaultReplyChannelName)) {
        gateway.setReplyChannelName(this.defaultReplyChannelName);
    } else {
        gateway.setReplyChannel(this.defaultReplyChannel);
    }
    if (requestTimeout == null) {
        gateway.setRequestTimeout(-1);
    } else if (requestTimeout instanceof ValueExpression) {
        gateway.setRequestTimeout(requestTimeout.getValue(Long.class));
    } else {
        messageMapper.setSendTimeoutExpression(requestTimeout);
    }
    if (replyTimeout == null) {
        gateway.setReplyTimeout(-1);
    } else if (replyTimeout instanceof ValueExpression) {
        gateway.setReplyTimeout(replyTimeout.getValue(Long.class));
    } else {
        messageMapper.setReplyTimeoutExpression(replyTimeout);
    }
    if (this.getBeanFactory() != null) {
        gateway.setBeanFactory(this.getBeanFactory());
    }
    if (replyTimeout != null) {
        gateway.setReceiveTimeoutExpression(replyTimeout);
    }
    gateway.setShouldTrack(this.shouldTrack);
    gateway.afterPropertiesSet();
    return gateway;
}
Also used : BeanInitializationException(org.springframework.beans.factory.BeanInitializationException) HashMap(java.util.HashMap) BeanDefinitionStoreException(org.springframework.beans.factory.BeanDefinitionStoreException) LiteralExpression(org.springframework.expression.common.LiteralExpression) Header(org.springframework.messaging.handler.annotation.Header) GatewayHeader(org.springframework.integration.annotation.GatewayHeader) LiteralExpression(org.springframework.expression.common.LiteralExpression) ValueExpression(org.springframework.integration.expression.ValueExpression) Expression(org.springframework.expression.Expression) Gateway(org.springframework.integration.annotation.Gateway) ValueExpression(org.springframework.integration.expression.ValueExpression) DefaultMessageBuilderFactory(org.springframework.integration.support.DefaultMessageBuilderFactory) MethodParameter(org.springframework.core.MethodParameter) GatewayHeader(org.springframework.integration.annotation.GatewayHeader) HashSet(java.util.HashSet)

Aggregations

HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 BeanDefinitionStoreException (org.springframework.beans.factory.BeanDefinitionStoreException)1 BeanInitializationException (org.springframework.beans.factory.BeanInitializationException)1 MethodParameter (org.springframework.core.MethodParameter)1 Expression (org.springframework.expression.Expression)1 LiteralExpression (org.springframework.expression.common.LiteralExpression)1 Gateway (org.springframework.integration.annotation.Gateway)1 GatewayHeader (org.springframework.integration.annotation.GatewayHeader)1 ValueExpression (org.springframework.integration.expression.ValueExpression)1 DefaultMessageBuilderFactory (org.springframework.integration.support.DefaultMessageBuilderFactory)1 Header (org.springframework.messaging.handler.annotation.Header)1