org.springframework.cloud.stream.binder.BinderHeaders Java Examples

The following examples show how to use org.springframework.cloud.stream.binder.BinderHeaders. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PartitionMessageQueueSelector.java    From spring-cloud-alibaba with Apache License 2.0 6 votes vote down vote up
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
	Integer partition = 0;
	try {
		partition = Math.abs(
				Integer.parseInt(msg.getProperty(BinderHeaders.PARTITION_HEADER)));
		if (partition >= mqs.size()) {
			LOGGER.warn(
					"the partition '{}' is greater than the number of queues '{}'.",
					partition, mqs.size());
			partition = partition % mqs.size();
		}
	}
	catch (NumberFormatException ignored) {
	}
	return mqs.get(partition);
}
 
Example #2
Source File: KinesisMessageChannelBinder.java    From spring-cloud-stream-binder-aws-kinesis with Apache License 2.0 6 votes vote down vote up
@Override
protected MessageHandler createProducerMessageHandler(ProducerDestination destination,
		ExtendedProducerProperties<KinesisProducerProperties> producerProperties,
		MessageChannel errorChannel) {

	FunctionExpression<Message<?>> partitionKeyExpression =
			new FunctionExpression<>((m) ->
					m.getHeaders().containsKey(BinderHeaders.PARTITION_HEADER)
							? m.getHeaders().get(BinderHeaders.PARTITION_HEADER)
							: m.getPayload().hashCode());
	final AbstractAwsMessageHandler<?> messageHandler;
	if (this.configurationProperties.isKplKclEnabled()) {
		messageHandler = createKplMessageHandler(destination, partitionKeyExpression);
	}
	else {
		messageHandler = createKinesisMessageHandler(destination, partitionKeyExpression);
	}
	messageHandler.setSync(producerProperties.getExtension().isSync());
	messageHandler.setSendTimeout(producerProperties.getExtension().getSendTimeout());
	messageHandler.setFailureChannel(errorChannel);
	messageHandler.setBeanFactory(getBeanFactory());

	this.streamsInUse.add(destination.getName());

	return messageHandler;
}
 
Example #3
Source File: KinesisMessageChannelBinder.java    From spring-cloud-stream-binder-aws-kinesis with Apache License 2.0 6 votes vote down vote up
private static String[] headersToMap(KinesisBinderConfigurationProperties configurationProperties) {
	Assert.notNull(configurationProperties,
			"'configurationProperties' must not be null");
	if (ObjectUtils.isEmpty(configurationProperties.getHeaders())) {
		return BinderHeaders.STANDARD_HEADERS;
	}
	else {
		String[] combinedHeadersToMap = Arrays.copyOfRange(
				BinderHeaders.STANDARD_HEADERS, 0,
				BinderHeaders.STANDARD_HEADERS.length
						+ configurationProperties.getHeaders().length);
		System.arraycopy(configurationProperties.getHeaders(), 0,
				combinedHeadersToMap, BinderHeaders.STANDARD_HEADERS.length,
				configurationProperties.getHeaders().length);
		return combinedHeadersToMap;
	}
}
 
Example #4
Source File: PartitionAwareFunctionWrapper.java    From spring-cloud-stream with Apache License 2.0 6 votes vote down vote up
@SuppressWarnings("unchecked")
PartitionAwareFunctionWrapper(FunctionInvocationWrapper function, ConfigurableApplicationContext context, ProducerProperties producerProperties) {
	this.function = function;
	if (producerProperties != null && producerProperties.isPartitioned()) {
		StandardEvaluationContext evaluationContext = ExpressionUtils.createStandardEvaluationContext(context.getBeanFactory());
		PartitionHandler partitionHandler = new PartitionHandler(evaluationContext, producerProperties, context.getBeanFactory());

		this.outputMessageEnricher = outputMessage -> {
			int partitionId = partitionHandler.determinePartition(outputMessage);
			return MessageBuilder
				.fromMessage(outputMessage)
				.setHeader(BinderHeaders.PARTITION_HEADER, partitionId).build();
		};
	}
	else {
		this.outputMessageEnricher = null;
	}
}
 
Example #5
Source File: MessageConverterConfigurer.java    From spring-cloud-stream with Apache License 2.0 6 votes vote down vote up
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
	if (!message.getHeaders().containsKey(BinderHeaders.PARTITION_OVERRIDE)) {
		int partition = this.partitionHandler.determinePartition(message);
		return MessageConverterConfigurer.this.messageBuilderFactory
				.fromMessage(message)
				.setHeader(BinderHeaders.PARTITION_HEADER, partition).build();
	}
	else {
		return MessageConverterConfigurer.this.messageBuilderFactory
				.fromMessage(message)
				.setHeader(BinderHeaders.PARTITION_HEADER,
						message.getHeaders()
								.get(BinderHeaders.PARTITION_OVERRIDE))
				.removeHeader(BinderHeaders.PARTITION_OVERRIDE).build();
	}
}
 
Example #6
Source File: KafkaMessageChannelBinder.java    From spring-cloud-stream-binder-kafka with Apache License 2.0 5 votes vote down vote up
private KafkaHeaderMapper getHeaderMapper(
		final ExtendedConsumerProperties<KafkaConsumerProperties> extendedConsumerProperties) {
	KafkaHeaderMapper mapper = null;
	if (this.configurationProperties.getHeaderMapperBeanName() != null) {
		mapper = getApplicationContext().getBean(
				this.configurationProperties.getHeaderMapperBeanName(),
				KafkaHeaderMapper.class);
	}
	if (mapper == null) {
		//First, try to see if there is a bean named headerMapper registered by other frameworks using the binder (for e.g. spring cloud sleuth)
		try {
			mapper = getApplicationContext().getBean("kafkaBinderHeaderMapper", KafkaHeaderMapper.class);
		}
		catch (BeansException be) {
			BinderHeaderMapper headerMapper = new BinderHeaderMapper() {

				@Override
				public void toHeaders(Headers source, Map<String, Object> headers) {
					super.toHeaders(source, headers);
					if (headers.size() > 0) {
						headers.put(BinderHeaders.NATIVE_HEADERS_PRESENT, Boolean.TRUE);
					}
				}

			};
			String[] trustedPackages = extendedConsumerProperties.getExtension()
					.getTrustedPackages();
			if (!StringUtils.isEmpty(trustedPackages)) {
				headerMapper.addTrustedPackages(trustedPackages);
			}
			mapper = headerMapper;
		}
	}
	return mapper;
}
 
Example #7
Source File: KafkaMessageChannelBinder.java    From spring-cloud-stream-binder-kafka with Apache License 2.0 5 votes vote down vote up
ProducerConfigurationMessageHandler(KafkaTemplate<byte[], byte[]> kafkaTemplate,
		String topic,
		ExtendedProducerProperties<KafkaProducerProperties> producerProperties,
		ProducerFactory<byte[], byte[]> producerFactory) {

	super(kafkaTemplate);
	if (producerProperties.getExtension().isUseTopicHeader()) {
		setTopicExpression(PARSER.parseExpression("headers['" + KafkaHeaders.TOPIC + "'] ?: '" + topic + "'"));
	}
	else {
		setTopicExpression(new LiteralExpression(topic));
	}
	Expression messageKeyExpression = producerProperties.getExtension().getMessageKeyExpression();
	if (expressionInterceptorNeeded(producerProperties)) {
		messageKeyExpression = PARSER.parseExpression("headers['"
				+ KafkaExpressionEvaluatingInterceptor.MESSAGE_KEY_HEADER
				+ "']");
	}
	setMessageKeyExpression(messageKeyExpression);
	setBeanFactory(KafkaMessageChannelBinder.this.getBeanFactory());
	if (producerProperties.isPartitioned()) {
		setPartitionIdExpression(PARSER.parseExpression(
				"headers['" + BinderHeaders.PARTITION_HEADER + "']"));
	}
	if (producerProperties.getExtension().isSync()) {
		setSync(true);
	}
	if (producerProperties.getExtension().getSendTimeoutExpression() != null) {
		setSendTimeoutExpression(producerProperties.getExtension().getSendTimeoutExpression());
	}
	this.producerFactory = producerFactory;
}
 
Example #8
Source File: BinderHeaderMapper.java    From spring-cloud-stream-binder-kafka with Apache License 2.0 5 votes vote down vote up
/**
 * Remove never headers.
 * @param headers the headers from which to remove the never headers.
 * @since 3.0.2
 */
public static void removeNeverHeaders(Headers headers) {
	headers.remove(MessageHeaders.ID);
	headers.remove(MessageHeaders.TIMESTAMP);
	headers.remove(IntegrationMessageHeaderAccessor.DELIVERY_ATTEMPT);
	headers.remove(BinderHeaders.NATIVE_HEADERS_PRESENT);
}
 
Example #9
Source File: RabbitMessageChannelBinder.java    From spring-cloud-stream-binder-rabbit with Apache License 2.0 5 votes vote down vote up
private Expression buildPartitionRoutingExpression(String expressionRoot,
		boolean rootIsExpression) {
	String partitionRoutingExpression = rootIsExpression
			? expressionRoot + " + '-' + headers['" + BinderHeaders.PARTITION_HEADER
					+ "']"
			: "'" + expressionRoot + "-' + headers['" + BinderHeaders.PARTITION_HEADER
					+ "']";
	return new SpelExpressionParser().parseExpression(partitionRoutingExpression);
}
 
Example #10
Source File: MessageChannelConfigurerTests.java    From spring-cloud-stream with Apache License 2.0 5 votes vote down vote up
@Test
public void testPartitionHeader() throws Exception {
	this.testSource.output()
			.send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").build());
	Message<?> message = this.messageCollector.forChannel(this.testSource.output())
			.poll(1, TimeUnit.SECONDS);
	assertThat(message.getHeaders().get(BinderHeaders.PARTITION_HEADER).equals(0));
	assertThat(message.getHeaders().get(BinderHeaders.PARTITION_OVERRIDE)).isNull();
}
 
Example #11
Source File: MessageChannelConfigurerTests.java    From spring-cloud-stream with Apache License 2.0 5 votes vote down vote up
@Test
public void testPartitionHeaderWithPartitionOverride() throws Exception {
	this.testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}")
			.setHeader(BinderHeaders.PARTITION_OVERRIDE, 123).build());
	Message<?> message = this.messageCollector.forChannel(this.testSource.output())
			.poll(1, TimeUnit.SECONDS);
	assertThat(message.getHeaders().get(BinderHeaders.PARTITION_HEADER).equals(123));
	assertThat(message.getHeaders().get(BinderHeaders.PARTITION_OVERRIDE)).isNull();
}
 
Example #12
Source File: KinesisBinderTests.java    From spring-cloud-stream-binder-aws-kinesis with Apache License 2.0 4 votes vote down vote up
@Test
@Override
public void testPartitionedModuleJava() throws Exception {
	KinesisTestBinder binder = getBinder();

	ExtendedConsumerProperties<KinesisConsumerProperties> consumerProperties = createConsumerProperties();
	consumerProperties.setConcurrency(2);
	consumerProperties.setInstanceCount(3);
	consumerProperties.setInstanceIndex(0);
	consumerProperties.setPartitioned(true);

	final List<Message<?>> results = new ArrayList<>();
	final CountDownLatch receiveLatch = new CountDownLatch(3);

	MessageHandler receivingHandler = (message) -> {
		results.add(message);
		receiveLatch.countDown();
	};

	DirectChannel input0 = createBindableChannelInternal("test.input0J", new BindingProperties(), true);
	input0.subscribe(receivingHandler);

	Binding<MessageChannel> input0Binding = binder.bindConsumer("partJ.0",
			"testPartitionedModuleJava", input0, consumerProperties);

	consumerProperties.setInstanceIndex(1);

	DirectChannel input1 = createBindableChannelInternal("test.input1J", new BindingProperties(), true);
	input1.subscribe(receivingHandler);

	Binding<MessageChannel> input1Binding = binder.bindConsumer("partJ.0",
			"testPartitionedModuleJava", input1, consumerProperties);

	consumerProperties.setInstanceIndex(2);

	DirectChannel input2 = createBindableChannelInternal("test.input2J", new BindingProperties(), true);
	input2.subscribe(receivingHandler);

	Binding<MessageChannel> input2Binding = binder.bindConsumer("partJ.0",
			"testPartitionedModuleJava", input2, consumerProperties);

	ExtendedProducerProperties<KinesisProducerProperties> producerProperties = createProducerProperties();

	producerProperties.setPartitionKeyExtractorName("partitionSupport");
	producerProperties.setPartitionSelectorName("partitionSupport");
	producerProperties.setPartitionCount(3);

	DirectChannel output = createBindableChannelInternal("test.output",
			createProducerBindingProperties(producerProperties), false);

	Binding<MessageChannel> outputBinding = binder.bindProducer("partJ.0", output,
			producerProperties);
	if (usesExplicitRouting()) {
		Object endpoint = extractEndpoint(outputBinding);
		assertThat(getEndpointRouting(endpoint))
				.contains(getExpectedRoutingBaseDestination("partJ.0",
						"testPartitionedModuleJava") + "-' + headers['"
						+ BinderHeaders.PARTITION_HEADER + "']");
	}

	output.send(new GenericMessage<>(2));
	output.send(new GenericMessage<>(1));
	output.send(new GenericMessage<>(0));

	assertThat(receiveLatch.await(20, TimeUnit.SECONDS)).isTrue();

	assertThat(results).extracting("payload").containsExactlyInAnyOrder(
			"0".getBytes(), "1".getBytes(), "2".getBytes());

	input0Binding.unbind();
	input1Binding.unbind();
	input2Binding.unbind();
	outputBinding.unbind();
}
 
Example #13
Source File: RabbitMessageChannelBinder.java    From spring-cloud-stream-binder-rabbit with Apache License 2.0 4 votes vote down vote up
@Override
protected MessageHandler createProducerMessageHandler(
		final ProducerDestination producerDestination,
		ExtendedProducerProperties<RabbitProducerProperties> producerProperties,
		MessageChannel errorChannel) {
	Assert.state(
			!HeaderMode.embeddedHeaders.equals(producerProperties.getHeaderMode()),
			"the RabbitMQ binder does not support embedded headers since RabbitMQ supports headers natively");
	String prefix = producerProperties.getExtension().getPrefix();
	String exchangeName = producerDestination.getName();
	String destination = StringUtils.isEmpty(prefix) ? exchangeName
			: exchangeName.substring(prefix.length());
	final AmqpOutboundEndpoint endpoint = new AmqpOutboundEndpoint(
			buildRabbitTemplate(producerProperties.getExtension(),
					errorChannel != null));
	endpoint.setExchangeName(producerDestination.getName());
	RabbitProducerProperties extendedProperties = producerProperties.getExtension();
	boolean expressionInterceptorNeeded = expressionInterceptorNeeded(
			extendedProperties);
	Expression routingKeyExpression = extendedProperties.getRoutingKeyExpression();
	if (!producerProperties.isPartitioned()) {
		if (routingKeyExpression == null) {
			endpoint.setRoutingKey(destination);
		}
		else {
			if (expressionInterceptorNeeded) {
				endpoint.setRoutingKeyExpressionString("headers['"
						+ RabbitExpressionEvaluatingInterceptor.ROUTING_KEY_HEADER
						+ "']");
			}
			else {
				endpoint.setRoutingKeyExpression(routingKeyExpression);
			}
		}
	}
	else {
		if (routingKeyExpression == null) {
			endpoint.setRoutingKeyExpression(
					buildPartitionRoutingExpression(destination, false));
		}
		else {
			if (expressionInterceptorNeeded) {
				endpoint.setRoutingKeyExpression(
						buildPartitionRoutingExpression("headers['"
								+ RabbitExpressionEvaluatingInterceptor.ROUTING_KEY_HEADER
								+ "']", true));
			}
			else {
				endpoint.setRoutingKeyExpression(buildPartitionRoutingExpression(
						routingKeyExpression.getExpressionString(), true));
			}
		}
	}
	if (extendedProperties.getDelayExpression() != null) {
		if (expressionInterceptorNeeded) {
			endpoint.setDelayExpressionString("headers['"
					+ RabbitExpressionEvaluatingInterceptor.DELAY_HEADER + "']");
		}
		else {
			endpoint.setDelayExpression(extendedProperties.getDelayExpression());
		}
	}
	DefaultAmqpHeaderMapper mapper = DefaultAmqpHeaderMapper.outboundMapper();
	List<String> headerPatterns = new ArrayList<>(extendedProperties.getHeaderPatterns().length + 3);
	headerPatterns.add("!" + BinderHeaders.PARTITION_HEADER);
	headerPatterns.add("!" + IntegrationMessageHeaderAccessor.SOURCE_DATA);
	headerPatterns.add("!" + IntegrationMessageHeaderAccessor.DELIVERY_ATTEMPT);
	headerPatterns.addAll(Arrays.asList(extendedProperties.getHeaderPatterns()));
	mapper.setRequestHeaderNames(
			headerPatterns.toArray(new String[headerPatterns.size()]));
	endpoint.setHeaderMapper(mapper);
	endpoint.setDefaultDeliveryMode(extendedProperties.getDeliveryMode());
	endpoint.setBeanFactory(this.getBeanFactory());
	if (errorChannel != null) {
		checkConnectionFactoryIsErrorCapable();
		endpoint.setReturnChannel(errorChannel);
		endpoint.setConfirmNackChannel(errorChannel);
		String ackChannelBeanName = StringUtils
				.hasText(extendedProperties.getConfirmAckChannel())
						? extendedProperties.getConfirmAckChannel()
						: IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME;
		if (!ackChannelBeanName.equals(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME)
				&& !getApplicationContext().containsBean(ackChannelBeanName)) {
			GenericApplicationContext context = (GenericApplicationContext) getApplicationContext();
			context.registerBean(ackChannelBeanName, DirectChannel.class,
					() -> new DirectChannel());
		}
		endpoint.setConfirmAckChannelName(ackChannelBeanName);
		endpoint.setConfirmCorrelationExpressionString("#root");
		endpoint.setErrorMessageStrategy(new DefaultErrorMessageStrategy());
	}
	endpoint.setHeadersMappedLast(true);
	return endpoint;
}
 
Example #14
Source File: RabbitBinderTests.java    From spring-cloud-stream-binder-rabbit with Apache License 2.0 4 votes vote down vote up
@Override
protected void checkRkExpressionForPartitionedModuleSpEL(Object endpoint) {
	assertThat(getEndpointRouting(endpoint))
			.contains(getExpectedRoutingBaseDestination("'part.0'", "test")
					+ " + '-' + headers['" + BinderHeaders.PARTITION_HEADER + "']");
}