@ -16,20 +16,24 @@
@@ -16,20 +16,24 @@
package org.springframework.cloud.netflix.eureka ;
import com.netflix.appinfo.DataCenterInfo ;
import com.netflix.appinfo.UniqueIdentifier ;
import com.netflix.appinfo.DataCenterInfo.Name ;
import com.netflix.appinfo.InstanceInfo ;
import com.netflix.appinfo.UniqueIdentifier ;
import com.netflix.discovery.converters.Converters.ApplicationsConverter ;
import com.netflix.discovery.converters.Converters.InstanceInfoConverter ;
import com.netflix.discovery.shared.Applications ;
import com.thoughtworks.xstream.MarshallingStrategy ;
import com.thoughtworks.xstream.converters.Converter ;
import com.thoughtworks.xstream.converters.ConverterLookup ;
import com.thoughtworks.xstream.converters.DataHolder ;
import com.thoughtworks.xstream.converters.MarshallingContext ;
import com.thoughtworks.xstream.converters.UnmarshallingContext ;
import com.thoughtworks.xstream.converters.* ;
import com.thoughtworks.xstream.core.TreeMarshallingStrategy ;
import com.thoughtworks.xstream.io.HierarchicalStreamReader ;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter ;
import com.thoughtworks.xstream.mapper.Mapper ;
import lombok.extern.slf4j.Slf4j ;
import org.aopalliance.intercept.MethodInterceptor ;
import org.aopalliance.intercept.MethodInvocation ;
import org.springframework.aop.framework.ProxyFactory ;
import org.springframework.cloud.client.discovery.DiscoveryHeartbeatEvent ;
import org.springframework.context.ApplicationContext ;
/ * *
* A special purpose wrapper for an XStream TreeMarshallingStrategy that is aware of the
@ -47,18 +51,23 @@ import com.thoughtworks.xstream.mapper.Mapper;
@@ -47,18 +51,23 @@ import com.thoughtworks.xstream.mapper.Mapper;
public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
private TreeMarshallingStrategy delegate = new TreeMarshallingStrategy ( ) ;
private ApplicationContext context ;
public DataCenterAwareMarshallingStrategy ( ApplicationContext context ) {
this . context = context ;
}
@Override
public Object unmarshal ( Object root , HierarchicalStreamReader reader ,
DataHolder dataHolder , ConverterLookup converterLookup , Mapper mapper ) {
ConverterLookup wrapped = new DataCenterAwareConverterLookup ( converterLookup ) ;
ConverterLookup wrapped = new DataCenterAwareConverterLookup ( converterLookup , context ) ;
return delegate . unmarshal ( root , reader , dataHolder , wrapped , mapper ) ;
}
@Override
public void marshal ( HierarchicalStreamWriter writer , Object obj ,
ConverterLookup converterLookup , Mapper mapper , DataHolder dataHolder ) {
ConverterLookup wrapped = new DataCenterAwareConverterLookup ( converterLookup ) ;
ConverterLookup wrapped = new DataCenterAwareConverterLookup ( converterLookup , context ) ;
delegate . marshal ( writer , obj , wrapped , mapper , dataHolder ) ;
}
@ -86,9 +95,11 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
@@ -86,9 +95,11 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
private static class DataCenterAwareConverterLookup implements ConverterLookup {
private ConverterLookup delegate ;
private ApplicationContext context ;
public DataCenterAwareConverterLookup ( ConverterLookup delegate ) {
public DataCenterAwareConverterLookup ( ConverterLookup delegate , ApplicationContext context ) {
this . delegate = delegate ;
this . context = context ;
}
@Override
@ -96,12 +107,52 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
@@ -96,12 +107,52 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
Converter converter = delegate . lookupConverterForType ( type ) ;
if ( InstanceInfo . class = = type ) {
return new DataCenterAwareConverter ( ) ;
} else if ( Applications . class = = type ) {
return new PublishingApplicationsConverter ( context ) ;
}
return converter ;
}
}
private static class PublishingApplicationsConverter extends ApplicationsConverter {
private ApplicationContext context ;
public PublishingApplicationsConverter ( ApplicationContext context ) {
this . context = context ;
}
@Override
public Object unmarshal ( HierarchicalStreamReader reader , UnmarshallingContext unmarshallingContext ) {
Object obj = super . unmarshal ( reader , unmarshallingContext ) ;
ProxyFactory factory = new ProxyFactory ( obj ) ;
factory . addAdvice ( new SetVersionInterceptor ( this . context ) ) ;
return factory . getProxy ( ) ;
}
}
@Slf4j
private static class SetVersionInterceptor implements MethodInterceptor {
private ApplicationContext context ;
public SetVersionInterceptor ( ApplicationContext context ) {
this . context = context ;
}
@Override
public Object invoke ( MethodInvocation invocation ) throws Throwable {
Object ret = invocation . proceed ( ) ;
if ( "setVersion" . equals ( invocation . getMethod ( ) . getName ( ) ) ) {
Long version = Long . class . cast ( invocation . getArguments ( ) [ 0 ] ) ;
log . debug ( "Applications.setVersion() called with version: " + version ) ;
context . publishEvent ( new DiscoveryHeartbeatEvent ( invocation . getThis ( ) , version ) ) ;
}
return ret ;
}
}
private static class DataCenterAwareConverter extends InstanceInfoConverter {
@Override