@Override public MetaData get() { if (metaData.isEmpty()){ if (map.isEmpty()) { metaData.add(emptyInstance()); } else { metaData.add(from(map.entrySet().stream().collect(toMap(Map.Entry::getKey, e -> convert(e.getValue()))))); } } return metaData.get(0); }
@Override public Map<String, MetaDataValue> apply(MetaData metaData) { Map<String, MetaDataValue> metaDataValueMap = new HashMap<>(); metaData.forEach((key, value)-> metaDataValueMap.put(key, metaDataConverter.convertToMetaDataValue(value))); return metaDataValueMap; } }
@Override public Map<String, ?> correlationDataFor(Message<?> message) { if (headerNames.length == 0) { return Collections.emptyMap(); } Map<String, Object> data = new HashMap<>(); final MetaData metaData = message.getMetaData(); for (String headerName : headerNames) { if (metaData.containsKey(headerName)) { data.put(headerName, metaData.get(headerName)); } } return data; } }
/** * Java Serialization specification method that will ensure that deserialization will maintain a single instance of * empty MetaData. * * @return the MetaData instance to use after deserialization */ protected Object readResolve() { if (isEmpty()) { return MetaData.emptyInstance(); } return this; }
/** * Returns a MetaData instances containing the current entries, <b>and</b> the given {@code key} if it was * not yet present in this MetaData. * If {@code key} already existed, the current value will be used. * Otherwise the Supplier function will provide the {@code value} for {@code key} * * @param key The key for the entry * @param value A Supplier function which provides the value * @return a MetaData instance with an additional entry */ public MetaData andIfNotPresent(String key, Supplier<Object> value) { return containsKey(key) ? this : this.and(key, value.get()); }
/** * Returns a MetaData instance containing values of {@code this}, combined with the given * {@code additionalEntries}. If any entries have identical keys, the values from the * {@code additionalEntries} will take precedence. * * @param additionalEntries The additional entries for the new MetaData * @return a MetaData instance containing values of {@code this}, combined with the given * {@code additionalEntries} */ public MetaData mergedWith(Map<String, ?> additionalEntries) { if (additionalEntries.isEmpty()) { return this; } if (isEmpty()) { return MetaData.from(additionalEntries); } Map<String, Object> merged = new HashMap<>(values); merged.putAll(additionalEntries); return new MetaData(merged); }
/** * Constructor to reconstruct a Message using existing data. Note that no correlation data * from a UnitOfWork is attached when using this constructor. If you're constructing a new * Message, use {@link #GenericMessage(Object, Map)} instead * * @param identifier The identifier of the Message * @param declaredPayloadType The declared type of message payload * @param payload The payload for the message * @param metaData The meta data for the message */ public GenericMessage(String identifier, Class<T> declaredPayloadType, T payload, Map<String, ?> metaData) { super(identifier); this.metaData = MetaData.from(metaData); this.payload = payload; this.payloadType = declaredPayloadType; }
/** * Initializes {@link GenericSubscriptionQueryUpdateMessage} with incremental update of provided {@code * declaredType}. * * @param declaredType the type of the update * @param payload the payload of the update */ public GenericSubscriptionQueryUpdateMessage(Class<U> declaredType, U payload) { this(declaredType, payload, MetaData.emptyInstance()); }
/** * Constructs a Message for the given {@code payload} and {@code meta data}. The given {@code metaData} is * merged with the MetaData from the correlation data of the current unit of work, if present. * * @param declaredPayloadType The declared type of message payload * @param payload The payload for the message * @param metaData The meta data for the message */ public GenericMessage(Class<T> declaredPayloadType, T payload, Map<String, ?> metaData) { this(IdentifierFactory.getInstance().generateIdentifier(), declaredPayloadType, payload, CurrentUnitOfWork.correlationData().mergedWith(MetaData.from(metaData))); }
/** * Finds the association property value by looking up the association property name in the event message's * {@link org.axonframework.messaging.MetaData}. */ @Override public <T> Object resolve(String associationPropertyName, EventMessage<?> message, MessageHandlingMember<T> handler) { return message.getMetaData().get(associationPropertyName); } }
@Override public GenericEventMessage<T> andMetaData(Map<String, ?> metaData) { if (metaData == null || metaData.isEmpty() || getMetaData().equals(metaData)) { return this; } return new GenericEventMessage<>(getDelegate().andMetaData(metaData), timestampSupplier); }
@Test public void testReturnedEventMessageBehavior() { testSubject.appendEvents(createEvent().withMetaData(singletonMap("key", "value"))); DomainEventMessage<?> messageWithMetaData = testSubject.readEvents(AGGREGATE).next(); /// we make sure persisted events have the same MetaData alteration logic DomainEventMessage<?> altered = messageWithMetaData.withMetaData(singletonMap("key2", "value")); DomainEventMessage<?> combined = messageWithMetaData.andMetaData(singletonMap("key2", "value")); assertTrue(altered.getMetaData().containsKey("key2")); altered.getPayload(); assertFalse(altered.getMetaData().containsKey("key")); assertTrue(altered.getMetaData().containsKey("key2")); assertTrue(combined.getMetaData().containsKey("key")); assertTrue(combined.getMetaData().containsKey("key2")); assertNotNull(messageWithMetaData.getPayload()); assertNotNull(messageWithMetaData.getMetaData()); assertFalse(messageWithMetaData.getMetaData().isEmpty()); }
@Override public Message<T> andMetaData(Map<String, ?> metaData) { if (metaData.isEmpty()) { return this; } return withMetaData(getMetaData().mergedWith(metaData)); }
@Override public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { MetaData metaData = (MetaData) source; if (!metaData.isEmpty()) { super.marshal(new HashMap<>(metaData), writer, context); } }
/** * Returns a MetaData instance containing values of {@code this}, combined with the given * {@code additionalEntries}. If any entries have identical keys, the values from the * {@code additionalEntries} will take precedence. * * @param additionalEntries The additional entries for the new MetaData * @return a MetaData instance containing values of {@code this}, combined with the given * {@code additionalEntries} */ public MetaData mergedWith(Map<String, ?> additionalEntries) { if (additionalEntries.isEmpty()) { return this; } if (isEmpty()) { return MetaData.from(additionalEntries); } Map<String, Object> merged = new HashMap<>(values); merged.putAll(additionalEntries); return new MetaData(merged); }
/** * Creates a MetaData instances with a single entry, with the given {@code key} and * given {@code value}. * * @param key The key for the entry * @param value The value of the entry * @return a MetaData instance with a single entry */ public static MetaData with(String key, Object value) { return MetaData.from(Collections.singletonMap(key, value)); }
/** * Constructs a Message for the given {@code payload} using the correlation data of the current Unit of Work, if * present. * * @param payload The payload for the message */ public GenericMessage(T payload) { this(payload, MetaData.emptyInstance()); }
/** * Constructs a Message for the given {@code payload} and {@code meta data}. The given {@code metaData} is * merged with the MetaData from the correlation data of the current unit of work, if present. * * @param declaredPayloadType The declared type of message payload * @param payload The payload for the message * @param metaData The meta data for the message */ public GenericMessage(Class<T> declaredPayloadType, T payload, Map<String, ?> metaData) { this(IdentifierFactory.getInstance().generateIdentifier(), declaredPayloadType, payload, CurrentUnitOfWork.correlationData().mergedWith(MetaData.from(metaData))); }