package com.netflix.discovery.converters;
import java.util.Iterator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.appinfo.AmazonInfo;
import com.netflix.appinfo.AmazonInfo.MetaDataKey;
import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.DataCenterInfo.Name;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.LeaseInfo;
import com.netflix.discovery.converters.jackson.AbstractEurekaJacksonCodec;
import com.netflix.discovery.converters.jackson.EurekaJsonJacksonCodec;
import com.netflix.discovery.converters.jackson.EurekaXmlJacksonCodec;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import com.netflix.discovery.util.EurekaEntityComparators;
import com.netflix.discovery.util.InstanceInfoGenerator;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
/**
* @author Tomasz Bak
*/
public class EurekaJsonAndXmlJacksonCodecTest {
private final InstanceInfoGenerator infoGenerator = InstanceInfoGenerator.newBuilder(4, 2).withMetaData(true).build();
private final Iterator<InstanceInfo> infoIterator = infoGenerator.serviceIterator();
@Test
public void testAmazonInfoEncodeDecodeWithJson() throws Exception {
doAmazonInfoEncodeDecodeTest(new EurekaJsonJacksonCodec());
}
@Test
public void testAmazonInfoEncodeDecodeWithXml() throws Exception {
doAmazonInfoEncodeDecodeTest(new EurekaXmlJacksonCodec());
}
private void doAmazonInfoEncodeDecodeTest(AbstractEurekaJacksonCodec codec) throws Exception {
AmazonInfo amazonInfo = (AmazonInfo) infoIterator.next().getDataCenterInfo();
String encodedString = codec.getObjectMapper(DataCenterInfo.class).writeValueAsString(amazonInfo);
DataCenterInfo decodedValue = codec.getObjectMapper(DataCenterInfo.class).readValue(encodedString, DataCenterInfo.class);
assertThat(EurekaEntityComparators.equal(amazonInfo, decodedValue), is(true));
}
@Test
public void testAmazonInfoCompactEncodeDecodeWithJson() throws Exception {
doAmazonInfoCompactEncodeDecodeTest(new EurekaJsonJacksonCodec(KeyFormatter.defaultKeyFormatter(), true));
}
@Test
public void testAmazonInfoCompactEncodeDecodeWithXml() throws Exception {
doAmazonInfoCompactEncodeDecodeTest(new EurekaXmlJacksonCodec(KeyFormatter.defaultKeyFormatter(), true));
}
private void doAmazonInfoCompactEncodeDecodeTest(AbstractEurekaJacksonCodec codec) throws Exception {
AmazonInfo amazonInfo = (AmazonInfo) infoIterator.next().getDataCenterInfo();
String encodedString = codec.getObjectMapper(DataCenterInfo.class).writeValueAsString(amazonInfo);
AmazonInfo decodedValue = (AmazonInfo) codec.getObjectMapper(DataCenterInfo.class).readValue(encodedString, DataCenterInfo.class);
assertThat(decodedValue.get(MetaDataKey.publicHostname), is(equalTo(amazonInfo.get(MetaDataKey.publicHostname))));
}
@Test
public void testMyDataCenterInfoEncodeDecodeWithJson() throws Exception {
doMyDataCenterInfoEncodeDecodeTest(new EurekaJsonJacksonCodec());
}
@Test
public void testMyDataCenterInfoEncodeDecodeWithXml() throws Exception {
doMyDataCenterInfoEncodeDecodeTest(new EurekaXmlJacksonCodec());
}
private void doMyDataCenterInfoEncodeDecodeTest(AbstractEurekaJacksonCodec codec) throws Exception {
DataCenterInfo myDataCenterInfo = new DataCenterInfo() {
@Override
public Name getName() {
return Name.MyOwn;
}
};
String encodedString = codec.getObjectMapper(DataCenterInfo.class).writeValueAsString(myDataCenterInfo);
DataCenterInfo decodedValue = codec.getObjectMapper(DataCenterInfo.class).readValue(encodedString, DataCenterInfo.class);
assertThat(decodedValue.getName(), is(equalTo(Name.MyOwn)));
}
@Test
public void testLeaseInfoEncodeDecodeWithJson() throws Exception {
doLeaseInfoEncodeDecode(new EurekaJsonJacksonCodec());
}
@Test
public void testLeaseInfoEncodeDecodeWithXml() throws Exception {
doLeaseInfoEncodeDecode(new EurekaXmlJacksonCodec());
}
private void doLeaseInfoEncodeDecode(AbstractEurekaJacksonCodec codec) throws Exception {
LeaseInfo leaseInfo = infoIterator.next().getLeaseInfo();
String encodedString = codec.getObjectMapper(LeaseInfo.class).writeValueAsString(leaseInfo);
LeaseInfo decodedValue = codec.getObjectMapper(LeaseInfo.class).readValue(encodedString, LeaseInfo.class);
assertThat(EurekaEntityComparators.equal(leaseInfo, decodedValue), is(true));
}
@Test
public void testInstanceInfoEncodeDecodeWithJson() throws Exception {
doInstanceInfoEncodeDecode(new EurekaJsonJacksonCodec());
}
@Test
public void testInstanceInfoEncodeDecodeWithXml() throws Exception {
doInstanceInfoEncodeDecode(new EurekaXmlJacksonCodec());
}
private void doInstanceInfoEncodeDecode(AbstractEurekaJacksonCodec codec) throws Exception {
InstanceInfo instanceInfo = infoIterator.next();
String encodedString = codec.getObjectMapper(InstanceInfo.class).writeValueAsString(instanceInfo);
InstanceInfo decodedValue = codec.getObjectMapper(InstanceInfo.class).readValue(encodedString, InstanceInfo.class);
assertThat(EurekaEntityComparators.equal(instanceInfo, decodedValue), is(true));
}
@Test
public void testInstanceInfoCompactEncodeDecodeWithJson() throws Exception {
doInstanceInfoCompactEncodeDecode(new EurekaJsonJacksonCodec(KeyFormatter.defaultKeyFormatter(), true), true);
}
@Test
public void testInstanceInfoCompactEncodeDecodeWithXml() throws Exception {
doInstanceInfoCompactEncodeDecode(new EurekaXmlJacksonCodec(KeyFormatter.defaultKeyFormatter(), true), false);
}
private void doInstanceInfoCompactEncodeDecode(AbstractEurekaJacksonCodec codec, boolean isJson) throws Exception {
InstanceInfo instanceInfo = infoIterator.next();
String encodedString = codec.getObjectMapper(InstanceInfo.class).writeValueAsString(instanceInfo);
if (isJson) {
JsonNode metadataNode = new ObjectMapper().readTree(encodedString).get("instance").get("metadata");
assertThat(metadataNode, is(nullValue()));
}
InstanceInfo decodedValue = codec.getObjectMapper(InstanceInfo.class).readValue(encodedString, InstanceInfo.class);
assertThat(decodedValue.getId(), is(equalTo(instanceInfo.getId())));
assertThat(decodedValue.getMetadata().isEmpty(), is(true));
}
@Test
public void testInstanceInfoIgnoredFieldsAreFilteredOutDuringDeserializationProcessWithJson() throws Exception {
doInstanceInfoIgnoredFieldsAreFilteredOutDuringDeserializationProcess(
new EurekaJsonJacksonCodec(),
new EurekaJsonJacksonCodec(KeyFormatter.defaultKeyFormatter(), true)
);
}
@Test
public void testInstanceInfoIgnoredFieldsAreFilteredOutDuringDeserializationProcessWithXml() throws Exception {
doInstanceInfoIgnoredFieldsAreFilteredOutDuringDeserializationProcess(
new EurekaXmlJacksonCodec(),
new EurekaXmlJacksonCodec(KeyFormatter.defaultKeyFormatter(), true)
);
}
public void doInstanceInfoIgnoredFieldsAreFilteredOutDuringDeserializationProcess(AbstractEurekaJacksonCodec fullCodec,
AbstractEurekaJacksonCodec compactCodec) throws Exception {
InstanceInfo instanceInfo = infoIterator.next();
// We use regular codec here to have all fields serialized
String encodedString = fullCodec.getObjectMapper(InstanceInfo.class).writeValueAsString(instanceInfo);
InstanceInfo decodedValue = compactCodec.getObjectMapper(InstanceInfo.class).readValue(encodedString, InstanceInfo.class);
assertThat(decodedValue.getId(), is(equalTo(instanceInfo.getId())));
assertThat(decodedValue.getAppName(), is(equalTo(instanceInfo.getAppName())));
assertThat(decodedValue.getIPAddr(), is(equalTo(instanceInfo.getIPAddr())));
assertThat(decodedValue.getVIPAddress(), is(equalTo(instanceInfo.getVIPAddress())));
assertThat(decodedValue.getSecureVipAddress(), is(equalTo(instanceInfo.getSecureVipAddress())));
assertThat(decodedValue.getHostName(), is(equalTo(instanceInfo.getHostName())));
assertThat(decodedValue.getStatus(), is(equalTo(instanceInfo.getStatus())));
assertThat(decodedValue.getActionType(), is(equalTo(instanceInfo.getActionType())));
assertThat(decodedValue.getASGName(), is(equalTo(instanceInfo.getASGName())));
assertThat(decodedValue.getLastUpdatedTimestamp(), is(equalTo(instanceInfo.getLastUpdatedTimestamp())));
AmazonInfo sourceAmazonInfo = (AmazonInfo) instanceInfo.getDataCenterInfo();
AmazonInfo decodedAmazonInfo = (AmazonInfo) decodedValue.getDataCenterInfo();
assertThat(decodedAmazonInfo.get(MetaDataKey.accountId), is(equalTo(sourceAmazonInfo.get(MetaDataKey.accountId))));
}
@Test
public void testInstanceInfoWithNoMetaEncodeDecodeWithJson() throws Exception {
doInstanceInfoWithNoMetaEncodeDecode(new EurekaJsonJacksonCodec(), true);
}
@Test
public void testInstanceInfoWithNoMetaEncodeDecodeWithXml() throws Exception {
doInstanceInfoWithNoMetaEncodeDecode(new EurekaXmlJacksonCodec(), false);
}
private void doInstanceInfoWithNoMetaEncodeDecode(AbstractEurekaJacksonCodec codec, boolean json) throws Exception {
InstanceInfo noMetaDataInfo = new InstanceInfo.Builder(infoIterator.next()).setMetadata(null).build();
String encodedString = codec.getObjectMapper(InstanceInfo.class).writeValueAsString(noMetaDataInfo);
// Backward compatibility with old codec
if (json) {
assertThat(encodedString.contains("\"@class\":\"java.util.Collections$EmptyMap\""), is(true));
}
InstanceInfo decodedValue = codec.getObjectMapper(InstanceInfo.class).readValue(encodedString, InstanceInfo.class);
assertThat(decodedValue.getId(), is(equalTo(noMetaDataInfo.getId())));
assertThat(decodedValue.getMetadata().isEmpty(), is(true));
}
@Test
public void testApplicationEncodeDecodeWithJson() throws Exception {
doApplicationEncodeDecode(new EurekaJsonJacksonCodec());
}
@Test
public void testApplicationEncodeDecodeWithXml() throws Exception {
doApplicationEncodeDecode(new EurekaXmlJacksonCodec());
}
private void doApplicationEncodeDecode(AbstractEurekaJacksonCodec codec) throws Exception {
Application application = new Application("testApp");
application.addInstance(infoIterator.next());
application.addInstance(infoIterator.next());
String encodedString = codec.getObjectMapper(Application.class).writeValueAsString(application);
Application decodedValue = codec.getObjectMapper(Application.class).readValue(encodedString, Application.class);
assertThat(EurekaEntityComparators.equal(application, decodedValue), is(true));
}
@Test
public void testApplicationsEncodeDecodeWithJson() throws Exception {
doApplicationsEncodeDecode(new EurekaJsonJacksonCodec());
}
@Test
public void testApplicationsEncodeDecodeWithXml() throws Exception {
doApplicationsEncodeDecode(new EurekaXmlJacksonCodec());
}
private void doApplicationsEncodeDecode(AbstractEurekaJacksonCodec codec) throws Exception {
Applications applications = infoGenerator.takeDelta(2);
String encodedString = codec.getObjectMapper(Applications.class).writeValueAsString(applications);
Applications decodedValue = codec.getObjectMapper(Applications.class).readValue(encodedString, Applications.class);
assertThat(EurekaEntityComparators.equal(applications, decodedValue), is(true));
}
}