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;
}
Aggregations