You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2017/05/26 09:40:16 UTC
curator git commit: Squashed commit of the following:
Repository: curator
Updated Branches:
refs/heads/CURATOR-2.0 abaabb5f6 -> ff02a7c2f
Squashed commit of the following:
commit 8cab83b4f7ecf44052eee8a30299f1adc3a50ce1
Merge: 3ca02ea7 abaabb5f
Author: randgalt <ra...@apache.org>
Date: Fri May 26 11:39:18 2017 +0200
Merge branch 'CURATOR-2.0' into CURATOR-394
commit 3ca02ea7f076d40333d664dd609962d0fe2e4c5f
Author: randgalt <ra...@apache.org>
Date: Thu May 18 11:39:20 2017 +0200
Added testForwardCompatibility
commit e7f55f89056f1447cb2ed73a0cdfd66759e11f91
Author: randgalt <ra...@apache.org>
Date: Fri Mar 31 13:25:04 2017 -0500
rename NewServiceInstance to make it clear it's only for testing
commit 6f3b178fdd6cc6ae914d4eead2ee74e4afbd5ec8
Author: randgalt <ra...@apache.org>
Date: Sun Mar 26 10:25:57 2017 -0500
updated tests
commit a193ce02c37d3ef5a6b9c4a81beffd4d8deba1d0
Author: randgalt <ra...@apache.org>
Date: Sun Mar 26 10:23:38 2017 -0500
Don't serialize enabled by default. This is the most compatible solution
commit 9ac224a3803c6d0ee4ed2081f36871e9d852f75c
Author: randgalt <ra...@apache.org>
Date: Fri Mar 24 20:04:30 2017 -0500
for safety check all the fields
commit ee18fd55f71e320050671541c7ed9435f3895a81
Author: randgalt <ra...@apache.org>
Date: Fri Mar 24 19:28:11 2017 -0500
bad commit
commit b6b9e1cc48b4713c1ded50c9d4c60a5071908e61
Author: randgalt <ra...@apache.org>
Date: Fri Mar 24 19:26:53 2017 -0500
bad commit
commit 070f1c9e4dae947ba21b015ea5027c3d20d170bd
Author: randgalt <ra...@apache.org>
Date: Fri Mar 24 19:22:48 2017 -0500
CURATOR-275 introduced a new field into ServiceInstance. This caused a potential UnrecognizedPropertyException in older clients that read newly serialized ServiceInstances. Added an alternate ctor to JsonInstanceSerializer with a compatibleSerializationMode option. when set to true, the new enabled field of ServiceInstance is not serialized.
Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/ff02a7c2
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/ff02a7c2
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/ff02a7c2
Branch: refs/heads/CURATOR-2.0
Commit: ff02a7c2fe33435df527d321d11964ba55851ad2
Parents: abaabb5
Author: randgalt <ra...@apache.org>
Authored: Fri May 26 11:40:00 2017 +0200
Committer: randgalt <ra...@apache.org>
Committed: Fri May 26 11:40:00 2017 +0200
----------------------------------------------------------------------
.../curator/x/discovery/ServiceInstance.java | 15 ++
.../details/JsonInstanceSerializer.java | 53 ++++-
.../x/discovery/details/OldServiceInstance.java | 196 +++++++++++++++++++
.../x/discovery/TestJsonInstanceSerializer.java | 16 +-
...TestJsonInstanceSerializerCompatibility.java | 107 ++++++++++
.../details/TestNewServiceInstance.java | 145 ++++++++++++++
6 files changed, 522 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/curator/blob/ff02a7c2/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceInstance.java
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceInstance.java b/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceInstance.java
index ebdd6bc..af2a2c7 100644
--- a/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceInstance.java
+++ b/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/ServiceInstance.java
@@ -82,6 +82,12 @@ public class ServiceInstance<T>
}
/**
+ * IMPORTANT: Due to CURATOR-275 the <code>enabled</code> field is <strong>NOT</strong> supported
+ * by default. If you wish to use the enabled field, you must set a {@link org.apache.curator.x.discovery.details.InstanceSerializer}
+ * that serializes this field. The default serializer, {@link org.apache.curator.x.discovery.details.JsonInstanceSerializer} does not
+ * serialize the field by default. You must use the alternate constructor {@link org.apache.curator.x.discovery.details.JsonInstanceSerializer#JsonInstanceSerializer(Class, boolean)}
+ * passing false for <code>compatibleSerializationMode</code>.
+ *
* @param name name of the service
* @param id id of this instance (must be unique)
* @param address address of this instance
@@ -164,6 +170,15 @@ public class ServiceInstance<T>
return uriSpec;
}
+ /**
+ * IMPORTANT: Due to CURATOR-275 the <code>enabled</code> field is <strong>NOT</strong> supported
+ * by default. If you wish to use the enabled field, you must set a {@link org.apache.curator.x.discovery.details.InstanceSerializer}
+ * that serializes this field. The default serializer, {@link org.apache.curator.x.discovery.details.JsonInstanceSerializer} does not
+ * serialize the field by default. You must use the alternate constructor {@link org.apache.curator.x.discovery.details.JsonInstanceSerializer#JsonInstanceSerializer(Class, boolean)}
+ * passing false for <code>compatibleSerializationMode</code>.
+ *
+ * @return true/false
+ */
public boolean isEnabled()
{
return enabled;
http://git-wip-us.apache.org/repos/asf/curator/blob/ff02a7c2/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/JsonInstanceSerializer.java
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/JsonInstanceSerializer.java b/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/JsonInstanceSerializer.java
index b7ddbc2..715ec1d 100644
--- a/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/JsonInstanceSerializer.java
+++ b/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/JsonInstanceSerializer.java
@@ -16,12 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.apache.curator.x.discovery.details;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.curator.x.discovery.ServiceInstance;
+import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
-import java.io.ByteArrayOutputStream;
/**
* A serializer that uses Jackson to serialize/deserialize as JSON. IMPORTANT: The instance
@@ -29,17 +31,51 @@ import java.io.ByteArrayOutputStream;
*/
public class JsonInstanceSerializer<T> implements InstanceSerializer<T>
{
- private final ObjectMapper mapper;
- private final Class<T> payloadClass;
- private final JavaType type;
+ private final ObjectMapper mapper;
+ private final Class<T> payloadClass;
+ private final boolean compatibleSerializationMode;
+ private final JavaType type;
/**
+ * CURATOR-275 introduced a new field into {@link org.apache.curator.x.discovery.ServiceInstance}. This caused a potential
+ * {@link org.codehaus.jackson.map.exc.UnrecognizedPropertyException} in older clients that
+ * read newly serialized ServiceInstances. Therefore the default behavior of JsonInstanceSerializer
+ * has been changed to <em>NOT</em> serialize the <code>enabled</code> field. If you wish to use that field, use the
+ * alternate constructor {@link #JsonInstanceSerializer(Class, boolean)} and pass true for
+ * <code>compatibleSerializationMode</code>. Note: future versions of Curator <em>may</em> change this
+ * behavior.
+ *
* @param payloadClass used to validate payloads when deserializing
*/
public JsonInstanceSerializer(Class<T> payloadClass)
{
+ this(payloadClass, true, false);
+ }
+
+ /**
+ * CURATOR-275 introduced a new field into {@link org.apache.curator.x.discovery.ServiceInstance}. This caused a potential
+ * {@link org.codehaus.jackson.map.exc.UnrecognizedPropertyException} in older clients that
+ * read newly serialized ServiceInstances. If you are susceptible to this you should set the
+ * serializer to be an instance of {@link org.apache.curator.x.discovery.details.JsonInstanceSerializer}
+ * with <code>compatibleSerializationMode</code> set to true. IMPORTANT: when this is done, the new <code>enabled</code>
+ * field of ServiceInstance is <strong>not</strong> serialized. If however you <em>do</em> want
+ * to use the <code>enabled</code> field, set <code>compatibleSerializationMode</code> to false.
+ *
+ * @param payloadClass used to validate payloads when deserializing
+ * @param compatibleSerializationMode pass true to serialize in a manner that supports clients pre-CURATOR-275
+ */
+ public JsonInstanceSerializer(Class<T> payloadClass, boolean compatibleSerializationMode)
+ {
+ this(payloadClass, compatibleSerializationMode, false);
+ }
+
+ @VisibleForTesting
+ JsonInstanceSerializer(Class<T> payloadClass, boolean compatibleSerializationMode, boolean failOnUnknownProperties)
+ {
this.payloadClass = payloadClass;
+ this.compatibleSerializationMode = compatibleSerializationMode;
mapper = new ObjectMapper();
+ mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, failOnUnknownProperties);
type = mapper.getTypeFactory().constructType(ServiceInstance.class);
}
@@ -55,8 +91,11 @@ public class JsonInstanceSerializer<T> implements InstanceSerializer<T>
@Override
public byte[] serialize(ServiceInstance<T> instance) throws Exception
{
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- mapper.writeValue(out, instance);
- return out.toByteArray();
+ if ( compatibleSerializationMode )
+ {
+ OldServiceInstance<T> compatible = new OldServiceInstance<T>(instance.getName(), instance.getId(), instance.getAddress(), instance.getPort(), instance.getSslPort(), instance.getPayload(), instance.getRegistrationTimeUTC(), instance.getServiceType(), instance.getUriSpec());
+ return mapper.writeValueAsBytes(compatible);
+ }
+ return mapper.writeValueAsBytes(instance);
}
}
http://git-wip-us.apache.org/repos/asf/curator/blob/ff02a7c2/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/OldServiceInstance.java
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/OldServiceInstance.java b/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/OldServiceInstance.java
new file mode 100644
index 0000000..253b274
--- /dev/null
+++ b/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/OldServiceInstance.java
@@ -0,0 +1,196 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.curator.x.discovery.details;
+
+import com.google.common.base.Preconditions;
+import org.apache.curator.x.discovery.ServiceType;
+import org.apache.curator.x.discovery.UriSpec;
+import org.codehaus.jackson.annotate.JsonTypeInfo;
+import org.codehaus.jackson.annotate.JsonTypeInfo.Id;
+
+/**
+ * POJO that represents a service instance
+ */
+class OldServiceInstance<T>
+{
+ private final String name;
+ private final String id;
+ private final String address;
+ private final Integer port;
+ private final Integer sslPort;
+ private final T payload;
+ private final long registrationTimeUTC;
+ private final ServiceType serviceType;
+ private final UriSpec uriSpec;
+
+ /**
+ * @param name name of the service
+ * @param id id of this instance (must be unique)
+ * @param address address of this instance
+ * @param port the port for this instance or null
+ * @param sslPort the SSL port for this instance or null
+ * @param payload the payload for this instance or null
+ * @param registrationTimeUTC the time (in UTC) of the registration
+ * @param serviceType type of the service
+ * @param uriSpec the uri spec or null
+ */
+ OldServiceInstance(String name, String id, String address, Integer port, Integer sslPort, T payload, long registrationTimeUTC, ServiceType serviceType, UriSpec uriSpec)
+ {
+ name = Preconditions.checkNotNull(name, "name cannot be null");
+ id = Preconditions.checkNotNull(id, "id cannot be null");
+
+ this.serviceType = serviceType;
+ this.uriSpec = uriSpec;
+ this.name = name;
+ this.id = id;
+ this.address = address;
+ this.port = port;
+ this.sslPort = sslPort;
+ this.payload = payload;
+ this.registrationTimeUTC = registrationTimeUTC;
+ }
+
+ OldServiceInstance()
+ {
+ this("", "", null, null, null, null, 0, ServiceType.DYNAMIC, null);
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getAddress()
+ {
+ return address;
+ }
+
+ public Integer getPort()
+ {
+ return port;
+ }
+
+ public Integer getSslPort()
+ {
+ return sslPort;
+ }
+
+ @JsonTypeInfo(use = Id.CLASS, defaultImpl = Object.class)
+ public T getPayload()
+ {
+ return payload;
+ }
+
+ public long getRegistrationTimeUTC()
+ {
+ return registrationTimeUTC;
+ }
+
+ public ServiceType getServiceType()
+ {
+ return serviceType;
+ }
+
+ public UriSpec getUriSpec()
+ {
+ return uriSpec;
+ }
+
+ @SuppressWarnings("RedundantIfStatement")
+ @Override
+ public boolean equals(Object o)
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+
+ OldServiceInstance that = (OldServiceInstance)o;
+
+ if ( registrationTimeUTC != that.registrationTimeUTC )
+ {
+ return false;
+ }
+ if ( address != null ? !address.equals(that.address) : that.address != null )
+ {
+ return false;
+ }
+ if ( id != null ? !id.equals(that.id) : that.id != null )
+ {
+ return false;
+ }
+ if ( name != null ? !name.equals(that.name) : that.name != null )
+ {
+ return false;
+ }
+ if ( payload != null ? !payload.equals(that.payload) : that.payload != null )
+ {
+ return false;
+ }
+ if ( port != null ? !port.equals(that.port) : that.port != null )
+ {
+ return false;
+ }
+ if ( serviceType != that.serviceType )
+ {
+ return false;
+ }
+ if ( sslPort != null ? !sslPort.equals(that.sslPort) : that.sslPort != null )
+ {
+ return false;
+ }
+ if ( uriSpec != null ? !uriSpec.equals(that.uriSpec) : that.uriSpec != null )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (id != null ? id.hashCode() : 0);
+ result = 31 * result + (address != null ? address.hashCode() : 0);
+ result = 31 * result + (port != null ? port.hashCode() : 0);
+ result = 31 * result + (sslPort != null ? sslPort.hashCode() : 0);
+ result = 31 * result + (payload != null ? payload.hashCode() : 0);
+ result = 31 * result + (int)(registrationTimeUTC ^ (registrationTimeUTC >>> 32));
+ result = 31 * result + (serviceType != null ? serviceType.hashCode() : 0);
+ result = 31 * result + (uriSpec != null ? uriSpec.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "ServiceInstance{" + "name='" + name + '\'' + ", id='" + id + '\'' + ", address='" + address + '\'' + ", port=" + port + ", sslPort=" + sslPort + ", payload=" + payload + ", registrationTimeUTC=" + registrationTimeUTC + ", serviceType=" + serviceType + ", uriSpec=" + uriSpec + '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/ff02a7c2/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/TestJsonInstanceSerializer.java
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/TestJsonInstanceSerializer.java b/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/TestJsonInstanceSerializer.java
index f17919d..0ed6c3d 100644
--- a/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/TestJsonInstanceSerializer.java
+++ b/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/TestJsonInstanceSerializer.java
@@ -98,7 +98,7 @@ public class TestJsonInstanceSerializer
@Test
public void testPayloadAsList() throws Exception
{
- JsonInstanceSerializer<Object> serializer = new JsonInstanceSerializer<Object>(Object.class);
+ JsonInstanceSerializer<Object> serializer = new JsonInstanceSerializer<Object>(Object.class, false);
List<String> payload = new ArrayList<String>();
payload.add("Test value 1");
payload.add("Test value 2");
@@ -121,7 +121,7 @@ public class TestJsonInstanceSerializer
@Test
public void testPayloadAsMap() throws Exception
{
- JsonInstanceSerializer<Object> serializer = new JsonInstanceSerializer<Object>(Object.class);
+ JsonInstanceSerializer<Object> serializer = new JsonInstanceSerializer<Object>(Object.class, false);
Map<String,String> payload = new HashMap<String,String>();
payload.put("1", "Test value 1");
payload.put("2", "Test value 2");
@@ -166,7 +166,17 @@ public class TestJsonInstanceSerializer
public String getVal() {
return val;
}
- public void setVal(String val) {
+
+ public Payload()
+ {
+ }
+
+ public Payload(String val)
+ {
+ this.val = val;
+ }
+
+ public void setVal(String val) {
this.val = val;
}
@Override
http://git-wip-us.apache.org/repos/asf/curator/blob/ff02a7c2/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestJsonInstanceSerializerCompatibility.java
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestJsonInstanceSerializerCompatibility.java b/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestJsonInstanceSerializerCompatibility.java
new file mode 100644
index 0000000..6e0e63e
--- /dev/null
+++ b/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestJsonInstanceSerializerCompatibility.java
@@ -0,0 +1,107 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.curator.x.discovery.details;
+
+import org.apache.curator.x.discovery.ServiceInstance;
+import org.apache.curator.x.discovery.ServiceType;
+import org.apache.curator.x.discovery.TestJsonInstanceSerializer;
+import org.apache.curator.x.discovery.UriSpec;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.JavaType;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import java.net.URI;
+import java.util.Date;
+
+public class TestJsonInstanceSerializerCompatibility
+{
+ @Test
+ public void testCompatibilityMode() throws Exception
+ {
+ JsonInstanceSerializer<TestJsonInstanceSerializer.Payload> serializer = new JsonInstanceSerializer<TestJsonInstanceSerializer.Payload>(TestJsonInstanceSerializer.Payload.class, true, true);
+ ServiceInstance<TestJsonInstanceSerializer.Payload> instance = new ServiceInstance<TestJsonInstanceSerializer.Payload>("name", "id", "address", 10, 20, new TestJsonInstanceSerializer.Payload("test"), 0, ServiceType.DYNAMIC, new UriSpec("{a}/b/{c}"), true);
+ byte[] bytes = serializer.serialize(instance);
+
+ OldServiceInstance<TestJsonInstanceSerializer.Payload> oldInstance = new OldServiceInstance<TestJsonInstanceSerializer.Payload>("name", "id", "address", 10, 20, new TestJsonInstanceSerializer.Payload("test"), 0, ServiceType.DYNAMIC, new UriSpec("{a}/b/{c}"));
+ ObjectMapper mapper = new ObjectMapper();
+ byte[] oldBytes = mapper.writeValueAsBytes(oldInstance);
+ Assert.assertEquals(bytes, oldBytes, String.format("%s vs %s", new String(bytes), new String(oldBytes)));
+ }
+
+ @Test
+ public void testBackwardCompatibility() throws Exception
+ {
+ JsonInstanceSerializer<TestJsonInstanceSerializer.Payload> serializer = new JsonInstanceSerializer<TestJsonInstanceSerializer.Payload>(TestJsonInstanceSerializer.Payload.class, true, true);
+ ServiceInstance<TestJsonInstanceSerializer.Payload> instance = new ServiceInstance<TestJsonInstanceSerializer.Payload>("name", "id", "address", 10, 20, new TestJsonInstanceSerializer.Payload("test"), 0, ServiceType.DYNAMIC, new UriSpec("{a}/b/{c}"), false);
+ byte[] bytes = serializer.serialize(instance);
+
+ instance = serializer.deserialize(bytes);
+ Assert.assertTrue(instance.isEnabled()); // passed false for enabled in the ctor but that is lost with compatibleSerializationMode
+
+ ObjectMapper mapper = new ObjectMapper();
+ JavaType type = mapper.getTypeFactory().constructType(OldServiceInstance.class);
+ OldServiceInstance rawServiceInstance = mapper.readValue(bytes, type);
+ TestJsonInstanceSerializer.Payload.class.cast(rawServiceInstance.getPayload()); // just to verify that it's the correct type
+ //noinspection unchecked
+ OldServiceInstance<TestJsonInstanceSerializer.Payload> check = (OldServiceInstance<TestJsonInstanceSerializer.Payload>)rawServiceInstance;
+ Assert.assertEquals(check.getName(), instance.getName());
+ Assert.assertEquals(check.getId(), instance.getId());
+ Assert.assertEquals(check.getAddress(), instance.getAddress());
+ Assert.assertEquals(check.getPort(), instance.getPort());
+ Assert.assertEquals(check.getSslPort(), instance.getSslPort());
+ Assert.assertEquals(check.getPayload(), instance.getPayload());
+ Assert.assertEquals(check.getRegistrationTimeUTC(), instance.getRegistrationTimeUTC());
+ Assert.assertEquals(check.getServiceType(), instance.getServiceType());
+ Assert.assertEquals(check.getUriSpec(), instance.getUriSpec());
+ }
+
+ @Test
+ public void testForwardCompatibility() throws Exception
+ {
+ OldServiceInstance<TestJsonInstanceSerializer.Payload> oldInstance = new OldServiceInstance<TestJsonInstanceSerializer.Payload>("name", "id", "address", 10, 20, new TestJsonInstanceSerializer.Payload("test"), 0, ServiceType.DYNAMIC, new UriSpec("{a}/b/{c}"));
+ ObjectMapper mapper = new ObjectMapper();
+ byte[] oldJson = mapper.writeValueAsBytes(oldInstance);
+
+ JsonInstanceSerializer<TestJsonInstanceSerializer.Payload> serializer = new JsonInstanceSerializer<TestJsonInstanceSerializer.Payload>(TestJsonInstanceSerializer.Payload.class);
+ ServiceInstance<TestJsonInstanceSerializer.Payload> instance = serializer.deserialize(oldJson);
+ Assert.assertEquals(oldInstance.getName(), instance.getName());
+ Assert.assertEquals(oldInstance.getId(), instance.getId());
+ Assert.assertEquals(oldInstance.getAddress(), instance.getAddress());
+ Assert.assertEquals(oldInstance.getPort(), instance.getPort());
+ Assert.assertEquals(oldInstance.getSslPort(), instance.getSslPort());
+ Assert.assertEquals(oldInstance.getPayload(), instance.getPayload());
+ Assert.assertEquals(oldInstance.getRegistrationTimeUTC(), instance.getRegistrationTimeUTC());
+ Assert.assertEquals(oldInstance.getServiceType(), instance.getServiceType());
+ Assert.assertEquals(oldInstance.getUriSpec(), instance.getUriSpec());
+ Assert.assertTrue(instance.isEnabled());
+ }
+
+ @Test
+ public void testFutureChanges() throws Exception
+ {
+ TestNewServiceInstance<String> newInstance = new TestNewServiceInstance<String>("name", "id", "address", 10, 20, "hey", 0, ServiceType.DYNAMIC, new UriSpec("{a}/b/{c}"), false, "what", 10101L, new Date(), new URI("http://hey"));
+ byte[] newInstanceBytes = new ObjectMapper().writeValueAsBytes(newInstance);
+ JsonInstanceSerializer<String> serializer = new JsonInstanceSerializer<String>(String.class);
+ ServiceInstance<String> instance = serializer.deserialize(newInstanceBytes);
+ Assert.assertEquals(instance.getName(), "name");
+ Assert.assertEquals(instance.getPayload(), "hey");
+ Assert.assertEquals(instance.isEnabled(), false);
+ }
+}
http://git-wip-us.apache.org/repos/asf/curator/blob/ff02a7c2/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestNewServiceInstance.java
----------------------------------------------------------------------
diff --git a/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestNewServiceInstance.java b/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestNewServiceInstance.java
new file mode 100644
index 0000000..e627474
--- /dev/null
+++ b/curator-x-discovery/src/test/java/org/apache/curator/x/discovery/details/TestNewServiceInstance.java
@@ -0,0 +1,145 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.curator.x.discovery.details;
+
+import com.google.common.base.Preconditions;
+import org.apache.curator.x.discovery.ServiceType;
+import org.apache.curator.x.discovery.UriSpec;
+import org.codehaus.jackson.annotate.JsonTypeInfo;
+import org.codehaus.jackson.annotate.JsonTypeInfo.Id;
+import java.net.URI;
+import java.util.Date;
+
+class TestNewServiceInstance<T>
+{
+ private final String name;
+ private final String id;
+ private final String address;
+ private final Integer port;
+ private final Integer sslPort;
+ private final T payload;
+ private final long registrationTimeUTC;
+ private final ServiceType serviceType;
+ private final UriSpec uriSpec;
+ private final boolean enabled;
+ private final String new1;
+ private final Long new2;
+ private final Date new3;
+ private final URI new4;
+
+ public TestNewServiceInstance(String name, String id, String address, Integer port, Integer sslPort, T payload, long registrationTimeUTC, ServiceType serviceType, UriSpec uriSpec, boolean enabled, String new1, Long new2, Date new3, URI new4)
+ {
+ name = Preconditions.checkNotNull(name, "name cannot be null");
+ id = Preconditions.checkNotNull(id, "id cannot be null");
+
+ this.new1 = new1;
+ this.new2 = new2;
+ this.new3 = new3;
+ this.new4 = new4;
+ this.serviceType = serviceType;
+ this.uriSpec = uriSpec;
+ this.name = name;
+ this.id = id;
+ this.address = address;
+ this.port = port;
+ this.sslPort = sslPort;
+ this.payload = payload;
+ this.registrationTimeUTC = registrationTimeUTC;
+ this.enabled = enabled;
+ }
+
+ /**
+ * Inits to default values. Only exists for deserialization
+ */
+ TestNewServiceInstance()
+ {
+ this("", "", null, null, null, null, 0, ServiceType.DYNAMIC, null, true, null, null, null, null);
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getAddress()
+ {
+ return address;
+ }
+
+ public Integer getPort()
+ {
+ return port;
+ }
+
+ public Integer getSslPort()
+ {
+ return sslPort;
+ }
+
+ @JsonTypeInfo(use = Id.CLASS, defaultImpl = Object.class)
+ public T getPayload()
+ {
+ return payload;
+ }
+
+ public long getRegistrationTimeUTC()
+ {
+ return registrationTimeUTC;
+ }
+
+ public ServiceType getServiceType()
+ {
+ return serviceType;
+ }
+
+ public UriSpec getUriSpec()
+ {
+ return uriSpec;
+ }
+
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ public String getNew1()
+ {
+ return new1;
+ }
+
+ public Long getNew2()
+ {
+ return new2;
+ }
+
+ public Date getNew3()
+ {
+ return new3;
+ }
+
+ public URI getNew4()
+ {
+ return new4;
+ }
+}