org.axonframework.spring.messaging.DefaultEventMessageConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of axon-spring Show documentation
Show all versions of axon-spring Show documentation
Module providing Spring specific helper functionality to ease configuration / set-up of an Axon application, as
well as some Spring specific infrastructure components.
The newest version!
/*
* Copyright (c) 2010-2018. Axon Framework
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.axonframework.spring.messaging;
import org.axonframework.eventhandling.DomainEventMessage;
import org.axonframework.eventhandling.EventMessage;
import org.axonframework.eventhandling.GenericDomainEventMessage;
import org.axonframework.eventhandling.GenericEventMessage;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.util.NumberUtils;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* An {@link EventMessageConverter} that will convert an Axon event message into a Spring message by:
*
* - Copying axon event payload into Spring message payload
* - Copying axon event metadata into Spring message headers
* - Adding axon event message specific attributes - that are not part of axon metadata - to the Spring message Headers.
* Among those specific attributes are {@link DomainEventMessage} specific properties
*
*
* @author Reda.Housni-Alaoui
* @since 3.1
*/
public class DefaultEventMessageConverter implements EventMessageConverter {
private static final String AXON_MESSAGE_PREFIX = "axon-message-";
private static final String MESSAGE_ID = AXON_MESSAGE_PREFIX + "id";
private static final String AGGREGATE_ID = AXON_MESSAGE_PREFIX + "aggregate-id";
private static final String AGGREGATE_SEQ = AXON_MESSAGE_PREFIX + "aggregate-seq";
private static final String AGGREGATE_TYPE = AXON_MESSAGE_PREFIX + "aggregate-type";
@Override
public Message convertToOutboundMessage(EventMessage event) {
Map headers = new HashMap<>();
event.getMetaData().forEach(headers::put);
headers.put(MESSAGE_ID, event.getIdentifier());
if (event instanceof DomainEventMessage) {
headers.put(AGGREGATE_ID, ((DomainEventMessage) event).getAggregateIdentifier());
headers.put(AGGREGATE_SEQ, ((DomainEventMessage) event).getSequenceNumber());
headers.put(AGGREGATE_TYPE, ((DomainEventMessage) event).getType());
}
return new GenericMessage<>(event.getPayload(), new SettableTimestampMessageHeaders(headers, event.getTimestamp().toEpochMilli()));
}
@Override
public EventMessage convertFromInboundMessage(Message message) {
MessageHeaders headers = message.getHeaders();
Map metaData = headers.entrySet()
.stream()
.filter(entry -> !entry.getKey().startsWith(AXON_MESSAGE_PREFIX))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
String messageId = Objects.toString(headers.get(MESSAGE_ID));
Long timestamp = headers.getTimestamp();
org.axonframework.messaging.GenericMessage genericMessage
= new org.axonframework.messaging.GenericMessage<>(messageId, message.getPayload(), metaData);
if (headers.containsKey(AGGREGATE_ID)) {
return new GenericDomainEventMessage<>(Objects.toString(headers.get(AGGREGATE_TYPE)),
Objects.toString(headers.get(AGGREGATE_ID)),
NumberUtils.convertNumberToTargetClass(headers.get(AGGREGATE_SEQ, Number.class), Long.class),
genericMessage, () -> Instant.ofEpochMilli(timestamp));
} else {
return new GenericEventMessage<>(genericMessage, () -> Instant.ofEpochMilli(timestamp));
}
}
private static class SettableTimestampMessageHeaders extends MessageHeaders {
protected SettableTimestampMessageHeaders(Map headers, Long timestamp) {
super(headers, null, timestamp);
}
}
}