Compatibility for independent bus clients (#76)
independent bus clients may not have all events implemented or the location of the event classes could be in a different package. This PR fixes issues in such an environment (e.g. Microservices). Therefore the event type in the AckRemoteApplicationEvent will be set via a special setter, so the availability of the type can be checked. In addition the UnknownRemoteApplicationEvent is fixed to not cause a NullPointerException when raised. Fixes #74
This commit is contained in:
committed by
Spencer Gibb
parent
00af9e26b0
commit
812100aa04
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.springframework.cloud.bus.event;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* An event that signals an ack of a specific {@link RemoteApplicationEvent}. These events
|
||||
* can be monitored by any applications that want to audit the responses to bus events.
|
||||
@@ -31,7 +33,7 @@ public class AckRemoteApplicationEvent extends RemoteApplicationEvent {
|
||||
|
||||
private final String ackId;
|
||||
private final String ackDestinationService;
|
||||
private final Class<? extends RemoteApplicationEvent> event;
|
||||
private Class<? extends RemoteApplicationEvent> event;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private AckRemoteApplicationEvent() {
|
||||
@@ -62,6 +64,21 @@ public class AckRemoteApplicationEvent extends RemoteApplicationEvent {
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by Jackson to set the remote class name of the event implementation. If the implementing class is unknown to
|
||||
* this app, set the event to {@link UnknownRemoteApplicationEvent}.
|
||||
*
|
||||
* @param eventName the fq class name of the event implementation, not null
|
||||
*/
|
||||
@JsonProperty("event")
|
||||
public void setEventName(String eventName) {
|
||||
try {
|
||||
event = (Class<? extends RemoteApplicationEvent>) Class.forName(eventName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
event = UnknownRemoteApplicationEvent.class;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
||||
@@ -34,7 +34,8 @@ public class UnknownRemoteApplicationEvent extends RemoteApplicationEvent {
|
||||
}
|
||||
|
||||
public UnknownRemoteApplicationEvent(Object source, String typeInfo, byte[] payload) {
|
||||
super(source, null, null);
|
||||
// Initialize originService with an empty String, to avoid NullPointer in AntPathMatcher.
|
||||
super(source, "", null);
|
||||
this.typeInfo = typeInfo;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati
|
||||
import org.springframework.cloud.bus.event.AckRemoteApplicationEvent;
|
||||
import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent;
|
||||
import org.springframework.cloud.bus.event.SentApplicationEvent;
|
||||
import org.springframework.cloud.bus.event.UnknownRemoteApplicationEvent;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
@@ -206,6 +207,19 @@ public class BusAutoConfigurationTests {
|
||||
this.context.getBean(InboundMessageHandlerConfiguration.class).refresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* see https://github.com/spring-cloud/spring-cloud-bus/issues/74
|
||||
*/
|
||||
@Test
|
||||
public void inboundNotFromSelfUnknown() {
|
||||
this.context = SpringApplication.run(InboundMessageHandlerConfiguration.class);
|
||||
this.context.setId("bar");
|
||||
this.context.getBean(SpringCloudBusClient.INPUT, MessageChannel.class)
|
||||
.send(new GenericMessage<>(
|
||||
new UnknownRemoteApplicationEvent(this, "UnknownEvent", "yada".getBytes())));
|
||||
// No Exception expected
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ MessageConsumer.class, BusAutoConfiguration.class,
|
||||
TestSupportBinderAutoConfiguration.class,
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.bus.event.AckRemoteApplicationEvent;
|
||||
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
|
||||
import org.springframework.cloud.bus.event.UnknownRemoteApplicationEvent;
|
||||
import org.springframework.cloud.bus.event.test.TestRemoteApplicationEvent;
|
||||
@@ -92,6 +93,36 @@ public class SubtypeModuleTests {
|
||||
assertTrue("event is wrong type", event instanceof TypedRemoteApplicationEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* see https://github.com/spring-cloud/spring-cloud-bus/issues/74
|
||||
*/
|
||||
@Test
|
||||
public void testDeserializeAckRemoteApplicationEventWithKnownType() throws Exception {
|
||||
BusJacksonMessageConverter converter = new BusJacksonAutoConfiguration().busJsonConverter();
|
||||
converter.afterPropertiesSet();
|
||||
Object event = converter.fromMessage(MessageBuilder.withPayload(
|
||||
"{\"type\":\"AckRemoteApplicationEvent\", \"event\":\"org.springframework.cloud.bus.event.test.TestRemoteApplicationEvent\"}")
|
||||
.build(), RemoteApplicationEvent.class);
|
||||
assertTrue("event is no ack", event instanceof AckRemoteApplicationEvent);
|
||||
AckRemoteApplicationEvent ackEvent = AckRemoteApplicationEvent.class.cast(event);
|
||||
assertEquals("inner ack event has wrong type", TestRemoteApplicationEvent.class, ackEvent.getEvent());
|
||||
}
|
||||
|
||||
/**
|
||||
* see https://github.com/spring-cloud/spring-cloud-bus/issues/74
|
||||
*/
|
||||
@Test
|
||||
public void testDeserializeAckRemoteApplicationEventWithUnknownType() throws Exception {
|
||||
BusJacksonMessageConverter converter = new BusJacksonAutoConfiguration().busJsonConverter();
|
||||
converter.afterPropertiesSet();
|
||||
Object event = converter.fromMessage(MessageBuilder.withPayload(
|
||||
"{\"type\":\"AckRemoteApplicationEvent\", \"event\":\"foo.bar.TestRemoteApplicationEvent\"}").build(),
|
||||
RemoteApplicationEvent.class);
|
||||
assertTrue("event is no ack", event instanceof AckRemoteApplicationEvent);
|
||||
AckRemoteApplicationEvent ackEvent = AckRemoteApplicationEvent.class.cast(event);
|
||||
assertEquals("inner ack event has wrong type", UnknownRemoteApplicationEvent.class, ackEvent.getEvent());
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@JsonTypeName("my")
|
||||
public static class MyRemoteApplicationEvent extends RemoteApplicationEvent {
|
||||
|
||||
Reference in New Issue
Block a user