This commit is contained in:
Spencer Gibb
2015-01-15 14:49:41 -07:00
parent 78f435ef29
commit e59f78b9ee
15 changed files with 175 additions and 157 deletions

View File

@@ -2,12 +2,7 @@ package org.springframework.cloud.bus.amqp;
import javax.annotation.PostConstruct;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.AnonymousQueue;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;

View File

@@ -16,7 +16,8 @@ public class AbstractBusEndpoint implements MvcEndpoint {
private String appId;
public AbstractBusEndpoint(ApplicationEventPublisher context, String appId, BusEndpoint busEndpoint) {
public AbstractBusEndpoint(ApplicationEventPublisher context, String appId,
BusEndpoint busEndpoint) {
this.context = context;
this.appId = appId;
this.delegate = busEndpoint;

View File

@@ -1,23 +1,23 @@
package org.springframework.cloud.bus.endpoint;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Collection;
import java.util.Collections;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Spencer Gibb
*/
@ConfigurationProperties(prefix = "endpoints.bus", ignoreUnknownFields = false)
public class BusEndpoint extends AbstractEndpoint<Collection<String>>/* implements MvcEndpoint*/ {
public class BusEndpoint extends AbstractEndpoint<Collection<String>> {
public BusEndpoint() {
super("bus");
}
public BusEndpoint() {
super("bus");
}
@Override
public Collection<String> invoke() {
return Collections.emptyList();
}
@Override
public Collection<String> invoke() {
return Collections.emptyList();
}
}

View File

@@ -14,17 +14,18 @@ import org.springframework.web.bind.annotation.ResponseBody;
*/
public class EnvironmentBusEndpoint extends AbstractBusEndpoint {
public EnvironmentBusEndpoint(ApplicationEventPublisher context, String id, BusEndpoint delegate) {
public EnvironmentBusEndpoint(ApplicationEventPublisher context, String id,
BusEndpoint delegate) {
super(context, id, delegate);
}
@RequestMapping(value = "env", method = RequestMethod.POST)
@ResponseBody
//TODO: make this an abstract method in AbstractBusEndpoint?
public void env(@RequestParam Map<String, String> params,
@RequestParam(value = "destination", required = false) String destination) {
publish(new EnvironmentChangeRemoteApplicationEvent(this, getInstanceId(), destination, params));
}
@RequestMapping(value = "env", method = RequestMethod.POST)
@ResponseBody
// TODO: make this an abstract method in AbstractBusEndpoint?
public void env(@RequestParam Map<String, String> params,
@RequestParam(value = "destination", required = false) String destination) {
publish(new EnvironmentChangeRemoteApplicationEvent(this, getInstanceId(),
destination, params));
}
}

View File

@@ -12,15 +12,16 @@ import org.springframework.web.bind.annotation.ResponseBody;
*/
public class RefreshBusEndpoint extends AbstractBusEndpoint {
public RefreshBusEndpoint(ApplicationEventPublisher context, String id, BusEndpoint delegate) {
public RefreshBusEndpoint(ApplicationEventPublisher context, String id,
BusEndpoint delegate) {
super(context, id, delegate);
}
@RequestMapping(value = "refresh", method = RequestMethod.POST)
@ResponseBody
public void refresh(@RequestParam(value = "destination", required = false) String destination) {
publish(new RefreshRemoteApplicationEvent(this, getInstanceId(), destination));
}
@ResponseBody
public void refresh(
@RequestParam(value = "destination", required = false) String destination) {
publish(new RefreshRemoteApplicationEvent(this, getInstanceId(), destination));
}
}

View File

@@ -1,26 +1,29 @@
package org.springframework.cloud.bus.event;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.cloud.context.environment.EnvironmentManager;
import java.util.Map;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.environment.EnvironmentManager;
import org.springframework.context.ApplicationListener;
/**
* @author Spencer Gibb
*/
@CommonsLog
public class EnvironmentChangeListener implements ApplicationListener<EnvironmentChangeRemoteApplicationEvent> {
@Autowired
private EnvironmentManager env;
public class EnvironmentChangeListener implements
ApplicationListener<EnvironmentChangeRemoteApplicationEvent> {
@Autowired
private EnvironmentManager env;
@Override
public void onApplicationEvent(EnvironmentChangeRemoteApplicationEvent event) {
Map<String, String> values = event.getValues();
log.info("Received remote environment change request. Keys/values to update " + values);
for (Map.Entry<String, String> entry: values.entrySet()) {
env.setProperty(entry.getKey(), entry.getValue());
}
}
@Override
public void onApplicationEvent(EnvironmentChangeRemoteApplicationEvent event) {
Map<String, String> values = event.getValues();
log.info("Received remote environment change request. Keys/values to update "
+ values);
for (Map.Entry<String, String> entry : values.entrySet()) {
env.setProperty(entry.getKey(), entry.getValue());
}
}
}

View File

@@ -10,22 +10,21 @@ import lombok.EqualsAndHashCode;
*/
@SuppressWarnings("serial")
@Data
@EqualsAndHashCode(callSuper=false)
@EqualsAndHashCode(callSuper = false)
public class EnvironmentChangeRemoteApplicationEvent extends RemoteApplicationEvent {
private final Map<String, String> values;
@SuppressWarnings("unused")
@SuppressWarnings("unused")
private EnvironmentChangeRemoteApplicationEvent() {
//for serializers
values = null;
}
// for serializers
values = null;
}
public EnvironmentChangeRemoteApplicationEvent(Object source, String originService,
String destinationService,
Map<String, String> values) {
super(source, originService, destinationService);
this.values = values;
}
public EnvironmentChangeRemoteApplicationEvent(Object source, String originService,
String destinationService, Map<String, String> values) {
super(source, originService, destinationService);
this.values = values;
}
}

View File

@@ -1,24 +1,26 @@
package org.springframework.cloud.bus.event;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.cloud.config.client.RefreshEndpoint;
import java.util.Arrays;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.config.client.RefreshEndpoint;
import org.springframework.context.ApplicationListener;
/**
* @author Spencer Gibb
*/
@CommonsLog
public class RefreshListener implements ApplicationListener<RefreshRemoteApplicationEvent> {
public class RefreshListener implements
ApplicationListener<RefreshRemoteApplicationEvent> {
@Autowired
private RefreshEndpoint endpoint;
@Autowired
private RefreshEndpoint endpoint;
@Override
public void onApplicationEvent(RefreshRemoteApplicationEvent event) {
String[] keys = endpoint.refresh();
log.info("Received remote refresh request. Keys refreshed " + Arrays.asList(keys));
}
@Override
public void onApplicationEvent(RefreshRemoteApplicationEvent event) {
String[] keys = endpoint.refresh();
log.info("Received remote refresh request. Keys refreshed " + Arrays.asList(keys));
}
}

View File

@@ -6,12 +6,13 @@ package org.springframework.cloud.bus.event;
@SuppressWarnings("serial")
public class RefreshRemoteApplicationEvent extends RemoteApplicationEvent {
@SuppressWarnings("unused")
private RefreshRemoteApplicationEvent(){
//for serializers
}
@SuppressWarnings("unused")
private RefreshRemoteApplicationEvent() {
// for serializers
}
public RefreshRemoteApplicationEvent(Object source, String originService, String destinationService) {
super(source, originService, destinationService);
}
public RefreshRemoteApplicationEvent(Object source, String originService,
String destinationService) {
super(source, originService, destinationService);
}
}

View File

@@ -1,39 +1,41 @@
package org.springframework.cloud.bus.event;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.context.ApplicationEvent;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
/**
* @author Spencer Gibb
*/
@SuppressWarnings("serial")
@Data
@EqualsAndHashCode(callSuper=false)
@EqualsAndHashCode(callSuper = false)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonIgnoreProperties("source")
public abstract class RemoteApplicationEvent extends ApplicationEvent {
private static final Object TRANSIENT_SOURCE = new Object();
private final String originService;
private final String destinationService;
private static final Object TRANSIENT_SOURCE = new Object();
private final String originService;
private final String destinationService;
protected RemoteApplicationEvent() {
//for serialization libs like jackson
super(TRANSIENT_SOURCE);
originService = null;
destinationService = null;
}
protected RemoteApplicationEvent() {
// for serialization libs like jackson
super(TRANSIENT_SOURCE);
originService = null;
destinationService = null;
}
protected RemoteApplicationEvent(Object source, String originService, String destinationService) {
super(source);
this.originService = originService;
this.destinationService = destinationService;
}
protected RemoteApplicationEvent(Object source, String originService,
String destinationService) {
super(source);
this.originService = originService;
this.destinationService = destinationService;
}
protected RemoteApplicationEvent(Object source, String originService) {
this(source, originService, null);
}
protected RemoteApplicationEvent(Object source, String originService) {
this(source, originService, null);
}
}

View File

@@ -1,6 +1,5 @@
package org.springframework.cloud.bus.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.bus.BusAutoConfiguration;
@@ -10,16 +9,19 @@ import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass({RefreshBusEndpoint.class, ObjectMapper.class})
@ConditionalOnClass({ RefreshBusEndpoint.class, ObjectMapper.class })
@AutoConfigureAfter(BusAutoConfiguration.class)
public class BusJacksonAutoConfiguration {
@Bean
public SubtypeModule basicBusSubtypeModule() {
return new SubtypeModule(RefreshRemoteApplicationEvent.class, EnvironmentChangeRemoteApplicationEvent.class);
}
@Bean
public SubtypeModule basicBusSubtypeModule() {
return new SubtypeModule(RefreshRemoteApplicationEvent.class,
EnvironmentChangeRemoteApplicationEvent.class);
}
}

View File

@@ -7,15 +7,15 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
*/
@SuppressWarnings("serial")
public class SubtypeModule extends SimpleModule {
private Class<?>[] subtypes;
private Class<?>[] subtypes;
public SubtypeModule(Class<?>... subtypes) {
this.subtypes = subtypes;
}
public SubtypeModule(Class<?>... subtypes) {
this.subtypes = subtypes;
}
@Override
public void setupModule(SetupContext context) {
context.registerSubtypes(subtypes);
super.setupModule(context);
}
@Override
public void setupModule(SetupContext context) {
context.registerSubtypes(subtypes);
super.setupModule(context);
}
}

View File

@@ -33,9 +33,9 @@ public class BusAutoConfigurationTests {
public void inboundNotForSelf() {
context = SpringApplication.run(InboundMessageHandlerConfiguration.class);
context.setId("foo");
context.getBean("cloudBusInboundChannel", MessageChannel.class)
.send(new GenericMessage<>(new RefreshRemoteApplicationEvent(this, "bar",
"bar")));
context.getBean("cloudBusInboundChannel", MessageChannel.class).send(
new GenericMessage<>(
new RefreshRemoteApplicationEvent(this, "bar", "bar")));
assertNull(context.getBean(InboundMessageHandlerConfiguration.class).event);
}

View File

@@ -4,16 +4,15 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author Dave Syer
*/
public class RefreshBusEndpointTests {
@Test
public void instanceId() throws Exception {
RefreshBusEndpoint endpoint = new RefreshBusEndpoint(null, "foo", new BusEndpoint());
RefreshBusEndpoint endpoint = new RefreshBusEndpoint(null, "foo",
new BusEndpoint());
assertEquals("foo", endpoint.getInstanceId());
}

View File

@@ -1,54 +1,66 @@
package org.springframework.cloud.bus.jackson;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
import static org.junit.Assert.*;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author Spencer Gibb
*/
public class SubtypeModuleTests {
@Test
public void testSubclass() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SubtypeModule(MyRemoteApplicationEvent.class));
@Test
public void testSubclass() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SubtypeModule(MyRemoteApplicationEvent.class));
RemoteApplicationEvent event = mapper.readValue("{\"type\":\"my\", \"destinationService\":\"myservice\", \"originService\":\"myorigin\"}", RemoteApplicationEvent.class);
assertTrue("event is wrong type", event instanceof MyRemoteApplicationEvent);
MyRemoteApplicationEvent myEvent = MyRemoteApplicationEvent.class.cast(event);
assertEquals("originService was wrong", "myorigin", myEvent.getOriginService());
assertEquals("destinationService was wrong", "myservice", myEvent.getDestinationService());
RemoteApplicationEvent event = mapper
.readValue(
"{\"type\":\"my\", \"destinationService\":\"myservice\", \"originService\":\"myorigin\"}",
RemoteApplicationEvent.class);
assertTrue("event is wrong type", event instanceof MyRemoteApplicationEvent);
MyRemoteApplicationEvent myEvent = MyRemoteApplicationEvent.class.cast(event);
assertEquals("originService was wrong", "myorigin", myEvent.getOriginService());
assertEquals("destinationService was wrong", "myservice",
myEvent.getDestinationService());
event = mapper.readValue("{\"type\":\"another\"}", AnotherRemoteApplicationEvent.class);
assertTrue("event is wrong type", event instanceof AnotherRemoteApplicationEvent);
}
event = mapper.readValue("{\"type\":\"another\"}",
AnotherRemoteApplicationEvent.class);
assertTrue("event is wrong type", event instanceof AnotherRemoteApplicationEvent);
}
@JsonTypeName("my")
public static class MyRemoteApplicationEvent extends RemoteApplicationEvent {
private MyRemoteApplicationEvent() {}
protected MyRemoteApplicationEvent(Object source, String originService, String destinationService) {
super(source, originService, destinationService);
}
@JsonTypeName("my")
public static class MyRemoteApplicationEvent extends RemoteApplicationEvent {
private MyRemoteApplicationEvent() {
}
protected MyRemoteApplicationEvent(Object source, String originService) {
super(source, originService);
}
}
protected MyRemoteApplicationEvent(Object source, String originService,
String destinationService) {
super(source, originService, destinationService);
}
protected MyRemoteApplicationEvent(Object source, String originService) {
super(source, originService);
}
}
@JsonTypeName("another")
public static class AnotherRemoteApplicationEvent extends RemoteApplicationEvent {
private AnotherRemoteApplicationEvent() {}
protected AnotherRemoteApplicationEvent(Object source, String originService, String destinationService) {
super(source, originService, destinationService);
}
@JsonTypeName("another")
public static class AnotherRemoteApplicationEvent extends RemoteApplicationEvent {
private AnotherRemoteApplicationEvent() {
}
protected AnotherRemoteApplicationEvent(Object source, String originService) {
super(source, originService);
}
}
protected AnotherRemoteApplicationEvent(Object source, String originService,
String destinationService) {
super(source, originService, destinationService);
}
protected AnotherRemoteApplicationEvent(Object source, String originService) {
super(source, originService);
}
}
}