Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#1560] Feature/intermediate representation data format #1561

Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,14 @@ public Instant getTimestamp() {
public LazyDeserializingObject<MetaData> getMetaData() {
return metaData;
}

@Override
public <D> Boolean canConvertDataTo(Class<D> requiredType) {
zambrovski marked this conversation as resolved.
Show resolved Hide resolved
return serializer.getConverter().canConvert(data.getContentType(), requiredType);
}

@Override
public Serializer getSerializer() {
zambrovski marked this conversation as resolved.
Show resolved Hide resolved
return serializer;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.axonframework.serialization.LazyDeserializingObject;
import org.axonframework.serialization.SerializedObject;
import org.axonframework.serialization.SerializedType;
import org.axonframework.serialization.Serializer;
smcvb marked this conversation as resolved.
Show resolved Hide resolved

import java.time.Instant;
import java.util.Optional;
Expand Down Expand Up @@ -139,4 +140,18 @@ <T> IntermediateEventRepresentation upcast(SerializedType outputType, Class<T> e
* @return the MetaData of the message wrapping the object to upcast, if available
*/
LazyDeserializingObject<MetaData> getMetaData();

/**
* Checks if the data can be converted to required type.
*
* @param requiredType the type to convert to
* @return true, if the intermediate representation can be converted to desired type.
zambrovski marked this conversation as resolved.
Show resolved Hide resolved
*/
<D> Boolean canConvertDataTo(Class<D> requiredType);
zambrovski marked this conversation as resolved.
Show resolved Hide resolved
zambrovski marked this conversation as resolved.
Show resolved Hide resolved

/**
* Retrieves the serializer used to retrieve data.
* @return serializer configured for event serialization.
zambrovski marked this conversation as resolved.
Show resolved Hide resolved
*/
Serializer getSerializer();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.axonframework.serialization.LazyDeserializingObject;
import org.axonframework.serialization.SerializedObject;
import org.axonframework.serialization.SerializedType;
import org.axonframework.serialization.Serializer;
import org.axonframework.serialization.SimpleSerializedObject;

import java.time.Instant;
Expand Down Expand Up @@ -136,4 +137,15 @@ public LazyDeserializingObject<MetaData> getMetaData() {
}
return metaData;
}

@Override
public <D> Boolean canConvertDataTo(Class<D> requiredType) {
return converter.canConvert(source.getData().getContentType(), requiredType);
}

@Override
public Serializer getSerializer() {
// upcasted representation has no serializer, ask the previous representation, until the InitialEventRepresentation answers the question.
return source.getSerializer();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2010-2020. 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.serialization.upcasting.event;

import org.axonframework.eventhandling.EventData;
import org.axonframework.eventhandling.GenericDomainEventMessage;
import org.axonframework.serialization.Converter;
import org.axonframework.serialization.Serializer;
import org.axonframework.serialization.xml.XStreamSerializer;
import org.axonframework.utils.TestDomainEventEntry;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

/**
* Test for intermediate representation.
*
* @author Simon Zambrovski
*/
public class IntermediateRepresentationTest {
zambrovski marked this conversation as resolved.
Show resolved Hide resolved

private final static Serializer serializer = XStreamSerializer.defaultSerializer();
zambrovski marked this conversation as resolved.
Show resolved Hide resolved

@Test
public void should_deliver_serializer() {
zambrovski marked this conversation as resolved.
Show resolved Hide resolved
EventData<?> eventData = new TestDomainEventEntry(
new GenericDomainEventMessage<>("test", "aggregateId", 0, "someString"), serializer
);
IntermediateEventRepresentation input = new InitialEventRepresentation(eventData, serializer);
EventUpcasterChain eventUpcasterChain = new EventUpcasterChain(
new IntermediateRepresentationTest.MyEventUpcaster(),
new IntermediateRepresentationTest.MyEventUpcaster(),
new IntermediateRepresentationTest.MyEventUpcaster()
);
List<IntermediateEventRepresentation> result = eventUpcasterChain.upcast(Stream.of(input)).collect(toList());
assertEquals(1, result.size());
IntermediateEventRepresentation output = result.get(0);
assertEquals(serializer, output.getSerializer());
}


@Test
public void can_convert_data_to() {
EventData<?> eventData = new TestDomainEventEntry(
new GenericDomainEventMessage<>("test", "aggregateId", 0, "someString"), serializer
);
Serializer serializer = mock(Serializer.class);
Converter converter = mock(Converter.class);
when(serializer.getConverter()).thenReturn(converter);
when(converter.canConvert(any(), eq(String.class))).thenReturn(true);

IntermediateEventRepresentation input = new InitialEventRepresentation(eventData, serializer);
EventUpcasterChain eventUpcasterChain = new EventUpcasterChain(
new IntermediateRepresentationTest.MyEventUpcaster()
);
List<IntermediateEventRepresentation> result = eventUpcasterChain.upcast(Stream.of(input)).collect(toList());
assertEquals(1, result.size());


assertEquals(true, input.canConvertDataTo(String.class));
assertEquals(true, result.get(0).canConvertDataTo(String.class));

verify(converter, atMostOnce()).canConvert(String.class, String.class);
}

private static class MyEventUpcaster extends SingleEventUpcaster {

@Override
protected boolean canUpcast(IntermediateEventRepresentation intermediateRepresentation) {
return true;
}

@Override
protected IntermediateEventRepresentation doUpcast(IntermediateEventRepresentation intermediateRepresentation) {
return new UpcastedEventRepresentation<>(
intermediateRepresentation.getType(),
intermediateRepresentation,
Function.identity(),
Function.identity(),
Object.class,
serializer.getConverter()
);
}
}
}