/** * Convert a plain {@link EventMessage} to a {@link DomainEventMessage}. If the message already is a {@link * DomainEventMessage} it will be returned as is. Otherwise a new {@link GenericDomainEventMessage} is made with * {@code null} type, aggegrateIdentifier equal to messageIdentifier and sequence number of 0L. * * @param eventMessage the input event message * @param <T> The type of payload in the message * @return the message converted to a domain event message */ public static <T> DomainEventMessage<T> asDomainEventMessage(EventMessage<T> eventMessage) { if (eventMessage instanceof DomainEventMessage<?>) { return (DomainEventMessage<T>) eventMessage; } return new GenericDomainEventMessage<>(null, eventMessage.getIdentifier(), 0L, eventMessage, eventMessage::getTimestamp); }
@Override protected void describeTo(StringBuilder stringBuilder) { super.describeTo(stringBuilder); stringBuilder.append('\'').append(", aggregateType='") .append(getType()).append('\'') .append(", aggregateIdentifier='") .append(getAggregateIdentifier()).append('\'') .append(", sequenceNumber=") .append(getSequenceNumber()); }
@Override protected void describeTo(StringBuilder stringBuilder) { super.describeTo(stringBuilder); stringBuilder.append(", trackingToken={") .append(trackingToken()) .append('}'); }
@Override public GenericDomainEventMessage<T> withMetaData(Map<String, ?> metaData) { if (getMetaData().equals(metaData)) { return this; } return new GenericDomainEventMessage<>(type, aggregateIdentifier, sequenceNumber, getDelegate().withMetaData(metaData), getTimestamp()); }
@Override public GenericDomainEventMessage<T> andMetaData(Map<String, ?> metaData) { if (metaData == null || metaData.isEmpty() || getMetaData().equals(metaData)) { return this; } return new GenericDomainEventMessage<>(type, aggregateIdentifier, sequenceNumber, getDelegate().andMetaData(metaData), getTimestamp()); }
@Override public <T> EventMessage<T> convertFromInboundMessage(Message<T> message) { MessageHeaders headers = message.getHeaders(); Map<String, ?> 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<T> 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)); } }
@Override public GenericDomainEventMessage<T> withMetaData(Map<String, ?> metaData) { if (getMetaData().equals(metaData)) { return this; } return new GenericDomainEventMessage<>(type, aggregateIdentifier, sequenceNumber, getDelegate().withMetaData(metaData), getTimestamp()); }
public Event map(EventMessage<?> eventMessage, Serializer serializer) { Event.Builder builder = Event.newBuilder(); if (eventMessage instanceof GenericDomainEventMessage) { builder.setAggregateIdentifier(((GenericDomainEventMessage) eventMessage).getAggregateIdentifier()) .setAggregateSequenceNumber(((GenericDomainEventMessage) eventMessage).getSequenceNumber()) .setAggregateType(((GenericDomainEventMessage) eventMessage).getType()); } SerializedObject<byte[]> serializedPayload = eventMessage.serializePayload(serializer, byte[].class); builder.setMessageIdentifier(eventMessage.getIdentifier()).setPayload( io.axoniq.axonserver.grpc.SerializedObject.newBuilder() .setType(serializedPayload.getType().getName()) .setRevision(getOrDefault( serializedPayload.getType().getRevision(), "" )) .setData(ByteString.copyFrom(serializedPayload.getData())) ).setTimestamp(eventMessage.getTimestamp().toEpochMilli()); eventMessage.getMetaData().forEach((k, v) -> builder.putMetaData(k, converter.convertToMetaDataValue(v))); return builder.build(); }
@Override protected void describeTo(StringBuilder stringBuilder) { super.describeTo(stringBuilder); stringBuilder.append(", trackingToken={") .append(trackingToken()) .append('}'); }
@Override public TestExecutor<T> andGiven(List<?> domainEvents) { for (Object event : domainEvents) { Object payload = event; MetaData metaData = null; if (event instanceof Message) { payload = ((Message) event).getPayload(); metaData = ((Message) event).getMetaData(); } this.givenEvents.add(new GenericDomainEventMessage<>(aggregateType.getSimpleName(), aggregateIdentifier, sequenceNumber++, new GenericMessage<>(payload, metaData), deadlineManager.getCurrentDateTime())); } return this; }
@Override public GenericDomainEventMessage<T> andMetaData(Map<String, ?> metaData) { if (metaData == null || metaData.isEmpty() || getMetaData().equals(metaData)) { return this; } return new GenericDomainEventMessage<>(type, aggregateIdentifier, sequenceNumber, getDelegate().andMetaData(metaData), getTimestamp()); }
@Override protected void describeTo(StringBuilder stringBuilder) { super.describeTo(stringBuilder); stringBuilder.append('\'').append(", aggregateType='") .append(getType()).append('\'') .append(", aggregateIdentifier='") .append(getAggregateIdentifier()).append('\'') .append(", sequenceNumber=") .append(getSequenceNumber()); }
public static DomainEventMessage<String> createEvent(long sequenceNumber, Instant timestamp) { return new GenericDomainEventMessage<>(TYPE, AGGREGATE, sequenceNumber, PAYLOAD, METADATA, IdentifierFactory.getInstance().generateIdentifier(), timestamp); }
public Event map(EventMessage<?> eventMessage, Serializer serializer) { Event.Builder builder = Event.newBuilder(); if (eventMessage instanceof GenericDomainEventMessage) { builder.setAggregateIdentifier(((GenericDomainEventMessage) eventMessage).getAggregateIdentifier()) .setAggregateSequenceNumber(((GenericDomainEventMessage) eventMessage).getSequenceNumber()) .setAggregateType(((GenericDomainEventMessage) eventMessage).getType()); } SerializedObject<byte[]> serializedPayload = eventMessage.serializePayload(serializer, byte[].class); builder.setMessageIdentifier(eventMessage.getIdentifier()).setPayload( io.axoniq.axonserver.grpc.SerializedObject.newBuilder() .setType(serializedPayload.getType().getName()) .setRevision(getOrDefault( serializedPayload.getType().getRevision(), "" )) .setData(ByteString.copyFrom(serializedPayload.getData())) ).setTimestamp(eventMessage.getTimestamp().toEpochMilli()); eventMessage.getMetaData().forEach((k, v) -> builder.putMetaData(k, converter.convertToMetaDataValue(v))); return builder.build(); }
public static DomainEventMessage<String> createEvent(long sequenceNumber, Instant timestamp) { return new GenericDomainEventMessage<>(TYPE, AGGREGATE, sequenceNumber, PAYLOAD, METADATA, IdentifierFactory.getInstance().generateIdentifier(), timestamp); }
public static DomainEventMessage<String> createEvent(String type, String eventId, String aggregateId, long sequenceNumber, String payload, MetaData metaData) { return new GenericDomainEventMessage<>(type, aggregateId, sequenceNumber, payload, metaData, eventId, GenericDomainEventMessage.clock.instant()); }
public static DomainEventMessage<String> createEvent(String type, String eventId, String aggregateId, long sequenceNumber, String payload, MetaData metaData) { return new GenericDomainEventMessage<>(type, aggregateId, sequenceNumber, payload, metaData, eventId, GenericDomainEventMessage.clock.instant()); }
ir::getTimestamp); } else { return new GenericDomainEventMessage<>(ir.getAggregateType().get(), ir.getAggregateIdentifier().get(), ir.getSequenceNumber().get(), serializedMessage, ir::getTimestamp);
@SuppressWarnings("unchecked") @Override protected DomainEventMessage createSnapshot(Class<?> aggregateType, String aggregateIdentifier, DomainEventStream eventStream) { DomainEventMessage firstEvent = eventStream.peek(); AggregateFactory<?> aggregateFactory = getAggregateFactory(aggregateType); if (aggregateFactory == null) { throw new IllegalArgumentException( "Aggregate Type is unknown in this snapshotter: " + aggregateType.getName() ); } aggregateModels.computeIfAbsent(aggregateType, k -> AnnotatedAggregateMetaModelFactory .inspectAggregate(k, parameterResolverFactory, handlerDefinition)); Object aggregateRoot = aggregateFactory.createAggregateRoot(aggregateIdentifier, firstEvent); SnapshotAggregate<Object> aggregate = new SnapshotAggregate(aggregateRoot, aggregateModels.get(aggregateType), repositoryProvider); aggregate.initializeState(eventStream); if (aggregate.isDeleted()) { return null; } return new GenericDomainEventMessage<>(aggregate.type(), aggregate.identifierAsString(), aggregate.version(), aggregate.getAggregateRoot()); }
@Test public void testPublicationOrderIsMaintained_AggregateAdded() { String aggregateId = UUID.randomUUID().toString(); GenericDomainEventMessage<StubAggregateCreatedEvent> event = new GenericDomainEventMessage<>("test", aggregateId, 0, new StubAggregateCreatedEvent(aggregateId)); when(eventStore.readEvents(aggregateId)).thenReturn(DomainEventStream.of(event)); doAnswer(invocation -> { System.out.println("Published event: " + invocation.getArguments()[0].toString()); return Void.class; }).when(eventStore).publish(isA(EventMessage.class)); commandBus.dispatch(asCommandMessage(new UpdateStubAggregateWithExtraEventCommand(aggregateId))); InOrder inOrder = inOrder(eventStore, eventStore, eventStore); inOrder.verify(eventStore).publish(isA(DomainEventMessage.class)); inOrder.verify(eventStore).publish(argThat(new NotADomainEventMatcher())); inOrder.verify(eventStore).publish(isA(DomainEventMessage.class)); }