Repository: curator Updated Branches: refs/heads/master 55d19fa04 -> c086d0a82
Squashed commit of the following: commit 8cab83b4f7ecf44052eee8a30299f1adc3a50ce1 Merge: 3ca02ea7 abaabb5f Author: randgalt <[email protected]> Date: Fri May 26 11:39:18 2017 +0200 Merge branch 'CURATOR-2.0' into CURATOR-394 commit 3ca02ea7f076d40333d664dd609962d0fe2e4c5f Author: randgalt <[email protected]> Date: Thu May 18 11:39:20 2017 +0200 Added testForwardCompatibility commit e7f55f89056f1447cb2ed73a0cdfd66759e11f91 Author: randgalt <[email protected]> Date: Fri Mar 31 13:25:04 2017 -0500 rename NewServiceInstance to make it clear it's only for testing commit 6f3b178fdd6cc6ae914d4eead2ee74e4afbd5ec8 Author: randgalt <[email protected]> Date: Sun Mar 26 10:25:57 2017 -0500 updated tests commit a193ce02c37d3ef5a6b9c4a81beffd4d8deba1d0 Author: randgalt <[email protected]> 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 <[email protected]> Date: Fri Mar 24 20:04:30 2017 -0500 for safety check all the fields commit ee18fd55f71e320050671541c7ed9435f3895a81 Author: randgalt <[email protected]> Date: Fri Mar 24 19:28:11 2017 -0500 bad commit commit b6b9e1cc48b4713c1ded50c9d4c60a5071908e61 Author: randgalt <[email protected]> Date: Fri Mar 24 19:26:53 2017 -0500 bad commit commit 070f1c9e4dae947ba21b015ea5027c3d20d170bd Author: randgalt <[email protected]> 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/527768de Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/527768de Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/527768de Branch: refs/heads/master Commit: 527768de890e163770aa4e2de084c7cb20bab82a Parents: 32a7755 Author: randgalt <[email protected]> Authored: Fri May 26 11:40:00 2017 +0200 Committer: randgalt <[email protected]> Committed: Fri May 26 11:41:06 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/527768de/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/527768de/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/527768de/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/527768de/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/527768de/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/527768de/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; + } +}
