From 6e84a997f5e21d4dbc4e8a4fb4d67803fc339a50 Mon Sep 17 00:00:00 2001 From: Achim Kraus Date: Thu, 12 Oct 2017 16:32:10 +0200 Subject: [PATCH] Use Identity as destination. Convert that Identity into a EndpointContext of a request. Signed-off-by: Achim Kraus Also-by: Simon Bernard --- .../eclipse/leshan/core/request/Identity.java | 60 +++++++++++++ ...aliforniumLwM2mBootstrapRequestSender.java | 33 ++++--- .../impl/CaliforniumLwM2mRequestSender.java | 6 +- .../californium/impl/CoapRequestBuilder.java | 28 +++--- .../impl/CaliforniumTestSupport.java | 6 +- .../impl/CoapRequestBuilderTest.java | 53 +++++------ .../impl/InMemoryRegistrationStoreTest.java | 9 +- .../impl/ObservationServiceTest.java | 5 +- .../cluster/serialization/IdentitySerDes.java | 87 +++++++++++++++++++ .../serialization/RegistrationSerDes.java | 6 +- .../RegistrationUpdateSerDes.java | 10 +-- .../serialization/ClientSerDesTest.java | 6 +- .../serialization/ClientUpdateSerDesTest.java | 6 +- .../server/bootstrap/BootstrapHandler.java | 3 +- .../LwM2mBootstrapRequestSender.java | 12 ++- .../server/registration/Registration.java | 46 +++++----- .../registration/RegistrationHandler.java | 7 +- .../registration/RegistrationUpdate.java | 50 +++++------ .../bootstrap/BootstrapHandlerTest.java | 6 +- .../RegistrationSortObjectLinksTest.java | 5 +- 20 files changed, 296 insertions(+), 148 deletions(-) create mode 100644 leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/IdentitySerDes.java diff --git a/leshan-core/src/main/java/org/eclipse/leshan/core/request/Identity.java b/leshan-core/src/main/java/org/eclipse/leshan/core/request/Identity.java index 2cb46487dc..e0d7505302 100644 --- a/leshan-core/src/main/java/org/eclipse/leshan/core/request/Identity.java +++ b/leshan-core/src/main/java/org/eclipse/leshan/core/request/Identity.java @@ -16,6 +16,7 @@ *******************************************************************************/ package org.eclipse.leshan.core.request; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.security.PublicKey; @@ -82,18 +83,34 @@ public static Identity unsecure(InetSocketAddress peerAddress) { return new Identity(peerAddress, null, null, null); } + public static Identity unsecure(InetAddress address, int port) { + return new Identity(new InetSocketAddress(address, port), null, null, null); + } + public static Identity psk(InetSocketAddress peerAddress, String identity) { return new Identity(peerAddress, identity, null, null); } + public static Identity psk(InetAddress address, int port, String identity) { + return new Identity(new InetSocketAddress(address, port), identity, null, null); + } + public static Identity rpk(InetSocketAddress peerAddress, PublicKey publicKey) { return new Identity(peerAddress, null, publicKey, null); } + public static Identity rpk(InetAddress address, int port, PublicKey publicKey) { + return new Identity(new InetSocketAddress(address, port), null, publicKey, null); + } + public static Identity x509(InetSocketAddress peerAddress, String commonName) { return new Identity(peerAddress, null, null, commonName); } + public static Identity x509(InetAddress address, int port, String commonName) { + return new Identity(new InetSocketAddress(address, port), null, null, commonName); + } + @Override public String toString() { if (pskIdentity != null) @@ -105,4 +122,47 @@ else if (x509CommonName != null) else return String.format("Identity %s[unsecure]", peerAddress); } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((peerAddress == null) ? 0 : peerAddress.hashCode()); + result = prime * result + ((pskIdentity == null) ? 0 : pskIdentity.hashCode()); + result = prime * result + ((rawPublicKey == null) ? 0 : rawPublicKey.hashCode()); + result = prime * result + ((x509CommonName == null) ? 0 : x509CommonName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Identity other = (Identity) obj; + if (peerAddress == null) { + if (other.peerAddress != null) + return false; + } else if (!peerAddress.equals(other.peerAddress)) + return false; + if (pskIdentity == null) { + if (other.pskIdentity != null) + return false; + } else if (!pskIdentity.equals(other.pskIdentity)) + return false; + if (rawPublicKey == null) { + if (other.rawPublicKey != null) + return false; + } else if (!rawPublicKey.equals(other.rawPublicKey)) + return false; + if (x509CommonName == null) { + if (other.x509CommonName != null) + return false; + } else if (!x509CommonName.equals(other.x509CommonName)) + return false; + return true; + } } diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mBootstrapRequestSender.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mBootstrapRequestSender.java index 30a6cc2dd8..4d05a57803 100644 --- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mBootstrapRequestSender.java +++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mBootstrapRequestSender.java @@ -15,8 +15,6 @@ *******************************************************************************/ package org.eclipse.leshan.server.californium.impl; -import java.net.InetSocketAddress; - import org.eclipse.californium.core.coap.MessageObserver; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.coap.Response; @@ -29,6 +27,7 @@ import org.eclipse.leshan.core.node.codec.LwM2mNodeDecoder; import org.eclipse.leshan.core.node.codec.LwM2mNodeEncoder; import org.eclipse.leshan.core.request.DownlinkRequest; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.response.ErrorCallback; import org.eclipse.leshan.core.response.LwM2mResponse; import org.eclipse.leshan.core.response.ResponseCallback; @@ -54,10 +53,10 @@ public CaliforniumLwM2mBootstrapRequestSender(Endpoint secureEndpoint, Endpoint } @Override - public T send(final String endpointName, final InetSocketAddress clientAddress, - final boolean secure, final DownlinkRequest request, long timeout) throws InterruptedException { - // Create the CoAP request from LwM2m request - CoapRequestBuilder coapClientRequestBuilder = new CoapRequestBuilder(clientAddress, model, encoder); + public T send(final String endpointName, final Identity destination, + final DownlinkRequest request, long timeout) throws InterruptedException { // Create the CoAP request + // from LwM2m request + CoapRequestBuilder coapClientRequestBuilder = new CoapRequestBuilder(destination, model, encoder); request.accept(coapClientRequestBuilder); final Request coapRequest = coapClientRequestBuilder.getRequest(); @@ -68,9 +67,8 @@ public T send(final String endpointName, final InetSoc public T buildResponse(Response coapResponse) { // TODO we need to fix that by removing the Client dependency from LwM2MResponseBuilder or by creating a // LwM2mBootstrapResponseBuilder - Registration registration = new Registration.Builder("fakeregistrationid", endpointName, - clientAddress.getAddress(), clientAddress.getPort(), - secure ? secureEndpoint.getAddress() : nonSecureEndpoint.getAddress()).build(); + Registration registration = new Registration.Builder("fakeregistrationid", endpointName, destination, + destination.isSecure() ? secureEndpoint.getAddress() : nonSecureEndpoint.getAddress()).build(); // Build LwM2m response LwM2mResponseBuilder lwm2mResponseBuilder = new LwM2mResponseBuilder<>(coapRequest, coapResponse, registration, model, null, decoder); @@ -81,7 +79,7 @@ public T buildResponse(Response coapResponse) { coapRequest.addMessageObserver(syncMessageObserver); // Send CoAP request asynchronously - if (secure) + if (destination.isSecure()) secureEndpoint.sendRequest(coapRequest); else nonSecureEndpoint.sendRequest(coapRequest); @@ -91,11 +89,11 @@ public T buildResponse(Response coapResponse) { } @Override - public void send(final String endpointName, final InetSocketAddress clientAddress, - final boolean secure, final DownlinkRequest request, final long timeout, - ResponseCallback responseCallback, ErrorCallback errorCallback) { + public void send(final String endpointName, final Identity destination, + final DownlinkRequest request, final long timeout, ResponseCallback responseCallback, + ErrorCallback errorCallback) { // Create the CoAP request from LwM2m request - CoapRequestBuilder coapClientRequestBuilder = new CoapRequestBuilder(clientAddress, model, encoder); + CoapRequestBuilder coapClientRequestBuilder = new CoapRequestBuilder(destination, model, encoder); request.accept(coapClientRequestBuilder); final Request coapRequest = coapClientRequestBuilder.getRequest(); @@ -105,9 +103,8 @@ public void send(final String endpointName, final Inet public T buildResponse(Response coapResponse) { // TODO we need to fix that by removing the Client dependency from LwM2MResponseBuilder or by creating a // LwM2mBootstrapResponseBuilder - Registration registration = new Registration.Builder("fakeregistrationid", endpointName, - clientAddress.getAddress(), clientAddress.getPort(), - secure ? secureEndpoint.getAddress() : nonSecureEndpoint.getAddress()).build(); + Registration registration = new Registration.Builder("fakeregistrationid", endpointName, destination, + destination.isSecure() ? secureEndpoint.getAddress() : nonSecureEndpoint.getAddress()).build(); // Build LwM2m response LwM2mResponseBuilder lwm2mResponseBuilder = new LwM2mResponseBuilder<>(coapRequest, coapResponse, @@ -119,7 +116,7 @@ public T buildResponse(Response coapResponse) { coapRequest.addMessageObserver(obs); // Send CoAP request asynchronously - if (secure) + if (destination.isSecure()) secureEndpoint.sendRequest(coapRequest); else nonSecureEndpoint.sendRequest(coapRequest); diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mRequestSender.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mRequestSender.java index 0d53c3b38e..e633025883 100644 --- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mRequestSender.java +++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CaliforniumLwM2mRequestSender.java @@ -12,6 +12,7 @@ * * Contributors: * Sierra Wireless - initial API and implementation + * Achim Kraus (Bosch Software Innovations GmbH) - use Identity as destination *******************************************************************************/ package org.eclipse.leshan.server.californium.impl; @@ -76,8 +77,7 @@ public T send(final Registration destination, final Do final LwM2mModel model = modelProvider.getObjectModel(destination); // Create the CoAP request from LwM2m request - CoapRequestBuilder coapRequestBuilder = new CoapRequestBuilder( - new InetSocketAddress(destination.getAddress(), destination.getPort()), destination.getRootPath(), + CoapRequestBuilder coapRequestBuilder = new CoapRequestBuilder(destination.getIdentity(), destination.getRootPath(), destination.getId(), destination.getEndpoint(), model, encoder); request.accept(coapRequestBuilder); final Request coapRequest = coapRequestBuilder.getRequest(); @@ -114,7 +114,7 @@ public void send(final Registration destination, final // Create the CoAP request from LwM2m request CoapRequestBuilder coapRequestBuilder = new CoapRequestBuilder( - new InetSocketAddress(destination.getAddress(), destination.getPort()), destination.getRootPath(), + destination.getIdentity(), destination.getRootPath(), destination.getId(), destination.getEndpoint(), model, encoder); request.accept(coapRequestBuilder); final Request coapRequest = coapRequestBuilder.getRequest(); diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilder.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilder.java index 2bc8ab2a83..75bc01128b 100644 --- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilder.java +++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilder.java @@ -12,13 +12,17 @@ * * Contributors: * Sierra Wireless - initial API and implementation + * Achim Kraus (Bosch Software Innovations GmbH) - use Identity as destination + * and transform them to + * EndpointContext for requests *******************************************************************************/ package org.eclipse.leshan.server.californium.impl; -import java.net.InetSocketAddress; import org.eclipse.californium.core.coap.MediaTypeRegistry; import org.eclipse.californium.core.coap.Request; +import org.eclipse.californium.elements.EndpointContext; +import org.eclipse.leshan.core.californium.ExchangeUtil; import org.eclipse.leshan.core.model.LwM2mModel; import org.eclipse.leshan.core.node.LwM2mObjectInstance; import org.eclipse.leshan.core.node.LwM2mPath; @@ -32,6 +36,7 @@ import org.eclipse.leshan.core.request.DiscoverRequest; import org.eclipse.leshan.core.request.DownlinkRequestVisitor; import org.eclipse.leshan.core.request.ExecuteRequest; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.request.ObserveRequest; import org.eclipse.leshan.core.request.ReadRequest; import org.eclipse.leshan.core.request.WriteAttributesRequest; @@ -44,7 +49,7 @@ public class CoapRequestBuilder implements DownlinkRequestVisitor { private Request coapRequest; // client information - private final InetSocketAddress destination; + private final Identity destination; private final String rootPath; private final String registrationId; private final String endpoint; @@ -52,7 +57,7 @@ public class CoapRequestBuilder implements DownlinkRequestVisitor { private final LwM2mModel model; private final LwM2mNodeEncoder encoder; - public CoapRequestBuilder(InetSocketAddress destination, LwM2mModel model, LwM2mNodeEncoder encoder) { + public CoapRequestBuilder(Identity destination, LwM2mModel model, LwM2mNodeEncoder encoder) { this.destination = destination; this.rootPath = null; this.registrationId = null; @@ -61,9 +66,8 @@ public CoapRequestBuilder(InetSocketAddress destination, LwM2mModel model, LwM2m this.encoder = encoder; } - public CoapRequestBuilder(InetSocketAddress destination, String rootPath, String registrationId, String endpoint, - LwM2mModel model, - LwM2mNodeEncoder encoder) { + public CoapRequestBuilder(Identity destination, String rootPath, String registrationId, String endpoint, + LwM2mModel model, LwM2mNodeEncoder encoder) { this.destination = destination; this.rootPath = rootPath; this.endpoint = endpoint; @@ -155,16 +159,16 @@ public void visit(BootstrapWriteRequest request) { public void visit(BootstrapDeleteRequest request) { coapRequest = Request.newDelete(); coapRequest.setConfirmable(true); - coapRequest.setDestination(destination.getAddress()); - coapRequest.setDestinationPort(destination.getPort()); + EndpointContext context = ExchangeUtil.extractContext(destination); + coapRequest.setDestinationContext(context); } @Override public void visit(BootstrapFinishRequest request) { coapRequest = Request.newPost(); coapRequest.setConfirmable(true); - coapRequest.setDestination(destination.getAddress()); - coapRequest.setDestinationPort(destination.getPort()); + EndpointContext context = ExchangeUtil.extractContext(destination); + coapRequest.setDestinationContext(context); // root path if (rootPath != null) { @@ -179,8 +183,8 @@ public void visit(BootstrapFinishRequest request) { } private final void setTarget(Request coapRequest, LwM2mPath path) { - coapRequest.setDestination(destination.getAddress()); - coapRequest.setDestinationPort(destination.getPort()); + EndpointContext context = ExchangeUtil.extractContext(destination); + coapRequest.setDestinationContext(context); // root path if (rootPath != null) { diff --git a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CaliforniumTestSupport.java b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CaliforniumTestSupport.java index 1e7a88ffd4..ce50866641 100644 --- a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CaliforniumTestSupport.java +++ b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CaliforniumTestSupport.java @@ -15,6 +15,7 @@ *******************************************************************************/ package org.eclipse.leshan.server.californium.impl; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; @@ -22,6 +23,7 @@ import java.util.concurrent.ThreadLocalRandom; import org.eclipse.leshan.LwM2m; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.server.registration.Registration; public class CaliforniumTestSupport { @@ -34,8 +36,8 @@ public class CaliforniumTestSupport { public void givenASimpleClient() throws UnknownHostException { registrationAddress = InetSocketAddress.createUnresolved("localhost", LwM2m.DEFAULT_COAP_PORT); - Registration.Builder builder = new Registration.Builder("ID", "urn:client", InetAddress.getLocalHost(), 10000, - registrationAddress); + Registration.Builder builder = new Registration.Builder("ID", "urn:client", + Identity.unsecure(Inet4Address.getLoopbackAddress(), 1000), registrationAddress); registration = builder.build(); } diff --git a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilderTest.java b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilderTest.java index 92fe362b20..75ac2db5ba 100644 --- a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilderTest.java +++ b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/CoapRequestBuilderTest.java @@ -40,6 +40,7 @@ import org.eclipse.leshan.core.request.DeleteRequest; import org.eclipse.leshan.core.request.DiscoverRequest; import org.eclipse.leshan.core.request.ExecuteRequest; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.request.ObserveRequest; import org.eclipse.leshan.core.request.ReadRequest; import org.eclipse.leshan.core.request.WriteAttributesRequest; @@ -72,8 +73,8 @@ private Registration newRegistration() throws UnknownHostException { } private Registration newRegistration(String rootpath) throws UnknownHostException { - Builder b = new Registration.Builder("regid", "endpoint", Inet4Address.getByName("127.0.0.1"), 12354, - new InetSocketAddress(0)); + Builder b = new Registration.Builder("regid", "endpoint", + Identity.unsecure(Inet4Address.getLoopbackAddress(), 12354), new InetSocketAddress(0)); if (rootpath != null) { Map attr = new HashMap<>(); attr.put("rt", "oma.lwm2m"); @@ -87,8 +88,8 @@ public void build_read_request() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); ReadRequest request = new ReadRequest(3, 0); builder.visit(request); @@ -105,8 +106,8 @@ public void build_read_request_with_non_default_object_path() throws Exception { Registration reg = newRegistration("/lwm2m"); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); ReadRequest request = new ReadRequest(3, 0, 1); builder.visit(request); @@ -120,8 +121,8 @@ public void build_read_request_with_root_path() throws Exception { Registration reg = newRegistration("/"); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); ReadRequest request = new ReadRequest(3); builder.visit(request); @@ -135,8 +136,8 @@ public void build_discover_request() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); DiscoverRequest request = new DiscoverRequest(3, 0); builder.visit(request); @@ -154,8 +155,8 @@ public void build_write_request() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); WriteRequest request = new WriteRequest(Mode.UPDATE, 3, 0, LwM2mSingleResource.newStringResource(4, "value")); builder.visit(request); @@ -178,8 +179,8 @@ public void build_write_request_replace() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); WriteRequest request = new WriteRequest(3, 0, 14, "value"); builder.visit(request); @@ -193,8 +194,8 @@ public void build_write_attribute_request() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); WriteAttributesRequest request = new WriteAttributesRequest(3, 0, 14, new ObserveSpec.Builder().minPeriod(10).maxPeriod(100).build()); builder.visit(request); @@ -212,8 +213,8 @@ public void build_execute_request() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); ExecuteRequest request = new ExecuteRequest(3, 0, 12, "params"); builder.visit(request); @@ -231,8 +232,8 @@ public void build_create_request__without_instance_id() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); CreateRequest request = new CreateRequest(12, LwM2mSingleResource.newStringResource(0, "value")); builder.visit(request); @@ -254,8 +255,8 @@ public void build_create_request__with_instance_id() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); CreateRequest request = new CreateRequest(12, new LwM2mObjectInstance(26, LwM2mSingleResource.newStringResource(0, "value"))); builder.visit(request); @@ -279,8 +280,8 @@ public void build_delete_request() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); DeleteRequest request = new DeleteRequest(12, 0); builder.visit(request); @@ -297,8 +298,8 @@ public void build_observe_request() throws Exception { Registration reg = newRegistration(); // test - CoapRequestBuilder builder = new CoapRequestBuilder(new InetSocketAddress(reg.getAddress(), reg.getPort()), - reg.getRootPath(), reg.getId(), reg.getEndpoint(), model, encoder); + CoapRequestBuilder builder = new CoapRequestBuilder(reg.getIdentity(), reg.getRootPath(), reg.getId(), + reg.getEndpoint(), model, encoder); ObserveRequest request = new ObserveRequest(12, 0); builder.visit(request); diff --git a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/InMemoryRegistrationStoreTest.java b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/InMemoryRegistrationStoreTest.java index 37f624e8fd..9f575ab7e0 100644 --- a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/InMemoryRegistrationStoreTest.java +++ b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/InMemoryRegistrationStoreTest.java @@ -22,6 +22,7 @@ import org.eclipse.leshan.Link; import org.eclipse.leshan.LwM2m; import org.eclipse.leshan.core.request.BindingMode; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.server.registration.Registration; import org.eclipse.leshan.server.registration.RegistrationStore; import org.eclipse.leshan.server.registration.RegistrationUpdate; @@ -54,7 +55,8 @@ public void update_registration_keeps_properties_unchanged() { givenASimpleRegistration(lifetime); store.addRegistration(registration); - RegistrationUpdate update = new RegistrationUpdate(registrationId, address, port, null, null, null, null); + RegistrationUpdate update = new RegistrationUpdate(registrationId, Identity.unsecure(address, port), null, null, + null, null); UpdatedRegistration updatedRegistration = store.updateRegistration(update); Assert.assertEquals(lifetime, updatedRegistration.getUpdatedRegistration().getLifeTimeInSec()); Assert.assertSame(binding, updatedRegistration.getUpdatedRegistration().getBindingMode()); @@ -81,7 +83,8 @@ public void update_registration_to_extend_time_to_live() { store.addRegistration(registration); Assert.assertFalse(registration.isAlive()); - RegistrationUpdate update = new RegistrationUpdate(registrationId, address, port, lifetime, null, null, null); + RegistrationUpdate update = new RegistrationUpdate(registrationId, Identity.unsecure(address, port), lifetime, + null, null, null); UpdatedRegistration updatedRegistration = store.updateRegistration(update); Assert.assertTrue(updatedRegistration.getUpdatedRegistration().isAlive()); @@ -91,7 +94,7 @@ public void update_registration_to_extend_time_to_live() { private void givenASimpleRegistration(Long lifetime) { - Registration.Builder builder = new Registration.Builder(registrationId, ep, address, port, + Registration.Builder builder = new Registration.Builder(registrationId, ep, Identity.unsecure(address, port), InetSocketAddress.createUnresolved("localhost", LwM2m.DEFAULT_COAP_PORT)); registration = builder.lifeTimeInSec(lifetime).smsNumber(sms).bindingMode(binding).objectLinks(objectLinks) diff --git a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/ObservationServiceTest.java b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/ObservationServiceTest.java index 7d71ecea51..d3298c339d 100644 --- a/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/ObservationServiceTest.java +++ b/leshan-server-cf/src/test/java/org/eclipse/leshan/server/californium/impl/ObservationServiceTest.java @@ -27,6 +27,7 @@ import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder; import org.eclipse.leshan.core.observation.Observation; import org.eclipse.leshan.core.request.ObserveRequest; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.server.californium.CaliforniumRegistrationStore; import org.eclipse.leshan.server.californium.ObserveUtil; import org.eclipse.leshan.server.model.StandardModelProvider; @@ -158,8 +159,8 @@ public Registration givenASimpleClient(String registrationId) { LwM2m.DEFAULT_COAP_PORT); Registration.Builder builder; try { - builder = new Registration.Builder(registrationId, registrationId + "_ep", InetAddress.getLocalHost(), - 10000, registrationAddress); + builder = new Registration.Builder(registrationId, registrationId + "_ep", + Identity.unsecure(InetAddress.getLocalHost(), 10000), registrationAddress); return builder.build(); } catch (UnknownHostException e) { throw new RuntimeException(e); diff --git a/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/IdentitySerDes.java b/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/IdentitySerDes.java new file mode 100644 index 0000000000..cdb33d3ad0 --- /dev/null +++ b/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/IdentitySerDes.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2017 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.html. + * + * Contributors: + * Achim Kraus (Bosch Software Innovations GmbH) - initial implementation. + ******************************************************************************/ +package org.eclipse.leshan.server.cluster.serialization; + +import java.net.InetSocketAddress; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import org.eclipse.californium.elements.EndpointContext; +import org.eclipse.leshan.core.request.Identity; +import org.eclipse.leshan.util.Hex; + +import com.eclipsesource.json.Json; +import com.eclipsesource.json.JsonObject; +import com.eclipsesource.json.JsonValue; + +/** + * Functions for serializing and deserializing a Californium {@link EndpointContext} in JSON. + */ +public class IdentitySerDes { + + private static final String KEY_ADDRESS = "address"; + private static final String KEY_PORT = "port"; + private static final String KEY_ID = "id"; + private static final String KEY_CN = "cn"; + private static final String KEY_RPK = "rpk"; + + public static JsonObject serialize(Identity identity) { + JsonObject o = Json.object(); + o.set(KEY_ADDRESS, identity.getPeerAddress().getHostString()); + o.set(KEY_PORT, identity.getPeerAddress().getPort()); + if (identity.isPSK()) { + o.set(KEY_ID, identity.getPskIdentity()); + } else if (identity.isRPK()) { + PublicKey publicKey = identity.getRawPublicKey(); + o.set(KEY_RPK, Hex.encodeHexString(publicKey.getEncoded())); + } else if (identity.isX509()) { + o.set(KEY_CN, identity.getX509CommonName()); + } + return o; + } + + public static Identity deserialize(JsonObject peer) { + String address = peer.get(KEY_ADDRESS).asString(); + int port = peer.get(KEY_PORT).asInt(); + + JsonValue jpsk = peer.get(KEY_ID); + if (jpsk != null) { + return Identity.psk(new InetSocketAddress(address, port), jpsk.asString()); + } + + JsonValue jrpk = peer.get(KEY_RPK); + if (jrpk != null) { + try { + byte[] rpk = Hex.decodeHex(jrpk.asString().toCharArray()); + X509EncodedKeySpec spec = new X509EncodedKeySpec(rpk); + PublicKey publicKey = KeyFactory.getInstance("EC").generatePublic(spec); + return Identity.rpk(new InetSocketAddress(address, port), publicKey); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + throw new IllegalStateException("Invalid security info content", e); + } + } + + JsonValue jcn = peer.get(KEY_CN); + if (jcn != null) { + return Identity.x509(new InetSocketAddress(address, port), jcn.asString()); + } + + return Identity.unsecure(new InetSocketAddress(address, port)); + } +} diff --git a/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationSerDes.java b/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationSerDes.java index 9d8277731f..230b3c34b5 100644 --- a/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationSerDes.java +++ b/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationSerDes.java @@ -37,8 +37,7 @@ public class RegistrationSerDes { public static JsonObject jSerialize(Registration r) { JsonObject o = Json.object(); o.add("regDate", r.getRegistrationDate().getTime()); - o.add("address", r.getAddress().getHostAddress()); - o.add("port", r.getPort()); + o.add("identity", IdentitySerDes.serialize(r.getIdentity())); o.add("regAddr", r.getRegistrationEndpointAddress().getHostString()); o.add("regPort", r.getRegistrationEndpointAddress().getPort()); o.add("lt", r.getLifeTimeInSec()); @@ -86,8 +85,7 @@ public static byte[] bSerialize(Registration r) { public static Registration deserialize(JsonObject jObj) { Registration.Builder b = new Registration.Builder(jObj.getString("regId", null), jObj.getString("ep", null), - new InetSocketAddress(jObj.getString("address", null), jObj.getInt("port", 0)).getAddress(), - jObj.getInt("port", 0), + IdentitySerDes.deserialize(jObj.get("identity").asObject()), new InetSocketAddress(jObj.getString("regAddr", null), jObj.getInt("regPort", 0))); b.bindingMode(BindingMode.valueOf(jObj.getString("bnd", null))); b.lastUpdate(new Date(jObj.getLong("lastUp", 0))); diff --git a/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDes.java b/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDes.java index e655f13def..b9e96f45d9 100644 --- a/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDes.java +++ b/leshan-server-cluster/src/main/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDes.java @@ -15,13 +15,13 @@ *******************************************************************************/ package org.eclipse.leshan.server.cluster.serialization; -import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import org.eclipse.leshan.Link; import org.eclipse.leshan.core.request.BindingMode; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.server.registration.RegistrationUpdate; import com.eclipsesource.json.Json; @@ -39,8 +39,7 @@ public static JsonObject jSerialize(RegistrationUpdate u) { // mandatory fields o.add("regId", u.getRegistrationId()); - o.add("address", u.getAddress().getHostAddress()); - o.add("port", u.getPort()); + o.add("identity", IdentitySerDes.serialize(u.getIdentity())); // optional fields if (u.getLifeTimeInSec() != null) @@ -84,8 +83,7 @@ public static RegistrationUpdate deserialize(byte[] data) throws UnknownHostExce // mandatory fields String regId = v.getString("regId", null); - InetAddress addr = InetAddress.getByName(v.getString("address", null)); - int port = v.getInt("port", -1); + Identity identity = IdentitySerDes.deserialize(v.get("identity").asObject()); // optional fields BindingMode b = null; @@ -124,6 +122,6 @@ public static RegistrationUpdate deserialize(byte[] data) throws UnknownHostExce } } - return new RegistrationUpdate(regId, addr, port, lifetime, sms, b, linkObjs); + return new RegistrationUpdate(regId, identity, lifetime, sms, b, linkObjs); } } \ No newline at end of file diff --git a/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientSerDesTest.java b/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientSerDesTest.java index 388d066bdf..ba339451a3 100644 --- a/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientSerDesTest.java +++ b/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientSerDesTest.java @@ -24,7 +24,7 @@ import java.util.Map; import org.eclipse.leshan.Link; -import org.eclipse.leshan.server.cluster.serialization.RegistrationSerDes; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.server.registration.Registration; import org.junit.Test; @@ -39,8 +39,8 @@ public void ser_and_des_are_equals() throws Exception { objs[0] = new Link("/0/1024/2", att); objs[1] = new Link("/0/2"); - Registration.Builder builder = new Registration.Builder("registrationId", "endpoint", Inet4Address.getByName("127.0.0.1"), - 1, new InetSocketAddress(212)).objectLinks(objs); + Registration.Builder builder = new Registration.Builder("registrationId", "endpoint", + Identity.unsecure(Inet4Address.getLoopbackAddress(), 1), new InetSocketAddress(212)).objectLinks(objs); builder.registrationDate(new Date(100L)); builder.lastUpdate(new Date(101L)); diff --git a/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientUpdateSerDesTest.java b/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientUpdateSerDesTest.java index abc951ebb3..b8087a2687 100644 --- a/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientUpdateSerDesTest.java +++ b/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/ClientUpdateSerDesTest.java @@ -24,6 +24,7 @@ import org.eclipse.leshan.Link; import org.eclipse.leshan.LwM2m; import org.eclipse.leshan.core.request.BindingMode; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.server.registration.RegistrationUpdate; import org.junit.Test; @@ -38,8 +39,9 @@ public void ser_and_des_are_equals() throws Exception { objs[0] = new Link("/0/1024/2", att); objs[1] = new Link("/0/2"); - RegistrationUpdate ru = new RegistrationUpdate("myId", Inet4Address.getByName("127.0.0.1"), - LwM2m.DEFAULT_COAP_PORT, 60000l, null, BindingMode.U, objs); + RegistrationUpdate ru = new RegistrationUpdate("myId", + Identity.unsecure(Inet4Address.getByName("127.0.0.1"), LwM2m.DEFAULT_COAP_PORT), 60000l, null, + BindingMode.U, objs); byte[] ser = RegistrationUpdateSerDes.bSerialize(ru); RegistrationUpdate ru2 = RegistrationUpdateSerDes.deserialize(ser); diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapHandler.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapHandler.java index 5d96b06fec..c7ac7afa87 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapHandler.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapHandler.java @@ -215,8 +215,7 @@ public void onError(Exception e) { private void send(BootstrapSession session, DownlinkRequest request, ResponseCallback responseCallback, ErrorCallback errorCallback) { - sender.send(session.getEndpoint(), session.getIdentity().getPeerAddress(), session.getIdentity().isSecure(), - request, DEFAULT_TIMEOUT, responseCallback, errorCallback); + sender.send(session.getEndpoint(), session.getIdentity(), request, DEFAULT_TIMEOUT, responseCallback, errorCallback); } private LwM2mObjectInstance convertToSecurityInstance(int instanceId, ServerSecurity securityConfig) { diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LwM2mBootstrapRequestSender.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LwM2mBootstrapRequestSender.java index b8d71949a8..1c5bb25cbd 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LwM2mBootstrapRequestSender.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/LwM2mBootstrapRequestSender.java @@ -15,9 +15,8 @@ *******************************************************************************/ package org.eclipse.leshan.server.bootstrap; -import java.net.InetSocketAddress; - import org.eclipse.leshan.core.request.DownlinkRequest; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.response.ErrorCallback; import org.eclipse.leshan.core.response.LwM2mResponse; import org.eclipse.leshan.core.response.ResponseCallback; @@ -29,13 +28,12 @@ public interface LwM2mBootstrapRequestSender { * @return the LWM2M response. The response can be null if the timeout (given parameter or CoAP * timeout) expires. */ - T send(String clientEndpoint, InetSocketAddress client, boolean secure, - DownlinkRequest request, long timeout) throws InterruptedException; + T send(String clientEndpoint, Identity client, DownlinkRequest request, long timeout) + throws InterruptedException; /** * Send a Lightweight M2M request asynchronously. */ - void send(String clientEndpoint, InetSocketAddress client, boolean secure, - DownlinkRequest request, long timeout, ResponseCallback responseCallback, - ErrorCallback errorCallback); + void send(String clientEndpoint, Identity client, DownlinkRequest request, + long timeout, ResponseCallback responseCallback, ErrorCallback errorCallback); } diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/Registration.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/Registration.java index dc802c4dc8..81f8d4d020 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/Registration.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/Registration.java @@ -12,6 +12,7 @@ * * Contributors: * Sierra Wireless - initial API and implementation + * Achim Kraus (Bosch Software Innovations GmbH) - use Identity as destination *******************************************************************************/ package org.eclipse.leshan.server.registration; @@ -27,6 +28,7 @@ import org.eclipse.leshan.Link; import org.eclipse.leshan.core.request.BindingMode; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.util.Validate; /** @@ -42,9 +44,7 @@ public class Registration implements Serializable { private final Date registrationDate; - private final InetAddress address; - - private final int port; + private final Identity identity; /* * The address of the LWM2M Server's CoAP end point the client used to register. @@ -75,7 +75,7 @@ public class Registration implements Serializable { private final Date lastUpdate; - protected Registration(String id, String endpoint, InetAddress address, int port, String lwM2mVersion, + protected Registration(String id, String endpoint, Identity identity, String lwM2mVersion, Long lifetimeInSec, String smsNumber, BindingMode bindingMode, Link[] objectLinks, InetSocketAddress registrationEndpointAddress, @@ -83,14 +83,12 @@ protected Registration(String id, String endpoint, InetAddress address, int port Validate.notNull(id); Validate.notEmpty(endpoint); - Validate.notNull(address); - Validate.notNull(port); + Validate.notNull(identity); Validate.notNull(registrationEndpointAddress); this.id = id; + this.identity = identity; this.endpoint = endpoint; - this.address = address; - this.port = port; this.smsNumber = smsNumber; this.registrationEndpointAddress = registrationEndpointAddress; @@ -130,13 +128,22 @@ public Date getRegistrationDate() { return registrationDate; } + /** + * Gets the clients identity. + * + * @return identity from client's most recent registration or registration update. + */ + public Identity getIdentity() { + return identity; + } + /** * Gets the client's network address. * * @return the source address from the client's most recent CoAP message. */ public InetAddress getAddress() { - return address; + return identity.getPeerAddress().getAddress(); } /** @@ -145,7 +152,7 @@ public InetAddress getAddress() { * @return the source port from the client's most recent CoAP message. */ public int getPort() { - return port; + return identity.getPeerAddress().getPort(); } /** @@ -288,8 +295,8 @@ public boolean usesQueueMode() { @Override public String toString() { return String.format( - "Registration [registrationDate=%s, address=%s, port=%s, registrationEndpoint=%s, lifeTimeInSec=%s, smsNumber=%s, lwM2mVersion=%s, bindingMode=%s, endpoint=%s, registrationId=%s, objectLinks=%s, lastUpdate=%s]", - registrationDate, address, port, registrationEndpointAddress, lifeTimeInSec, smsNumber, lwM2mVersion, + "Registration [registrationDate=%s, identity=%s, registrationEndpoint=%s, lifeTimeInSec=%s, smsNumber=%s, lwM2mVersion=%s, bindingMode=%s, endpoint=%s, registrationId=%s, objectLinks=%s, lastUpdate=%s]", + registrationDate, identity, registrationEndpointAddress, lifeTimeInSec, smsNumber, lwM2mVersion, bindingMode, endpoint, id, Arrays.toString(objectLinks), lastUpdate); } @@ -322,8 +329,7 @@ public boolean equals(Object obj) { public static class Builder { private final String registrationId; private final String endpoint; - private final InetAddress address; - private final int port; + private final Identity identity; private final InetSocketAddress registrationEndpointAddress; private Date registrationDate; @@ -335,18 +341,16 @@ public static class Builder { private Link[] objectLinks; private Map additionalRegistrationAttributes; - public Builder(String registrationId, String endpoint, InetAddress address, int port, + public Builder(String registrationId, String endpoint, Identity identity, InetSocketAddress registrationEndpointAddress) { Validate.notNull(registrationId); Validate.notEmpty(endpoint); - Validate.notNull(address); - Validate.notNull(port); + Validate.notNull(identity); Validate.notNull(registrationEndpointAddress); this.registrationId = registrationId; this.endpoint = endpoint; - this.address = address; - this.port = port; + this.identity = identity; this.registrationEndpointAddress = registrationEndpointAddress; } @@ -392,8 +396,8 @@ public Builder additionalRegistrationAttributes(Map additionalRe } public Registration build() { - return new Registration(Builder.this.registrationId, Builder.this.endpoint, Builder.this.address, - Builder.this.port, Builder.this.lwM2mVersion, Builder.this.lifeTimeInSec, Builder.this.smsNumber, + return new Registration(Builder.this.registrationId, Builder.this.endpoint, Builder.this.identity, + Builder.this.lwM2mVersion, Builder.this.lifeTimeInSec, Builder.this.smsNumber, this.bindingMode, this.objectLinks, this.registrationEndpointAddress, this.registrationDate, this.lastUpdate, this.additionalRegistrationAttributes); } diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationHandler.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationHandler.java index 7e4df1443e..39543d0b55 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationHandler.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationHandler.java @@ -12,6 +12,7 @@ * * Contributors: * Sierra Wireless - initial API and implementation + * Achim Kraus (Bosch Software Innovations GmbH) - use Identity as destination *******************************************************************************/ package org.eclipse.leshan.server.registration; @@ -52,8 +53,7 @@ public SendableResponse register(Identity sender, RegisterRequ InetSocketAddress serverEndpoint) { Registration.Builder builder = new Registration.Builder(RegistrationHandler.createRegistrationId(), - registerRequest.getEndpointName(), sender.getPeerAddress().getAddress(), - sender.getPeerAddress().getPort(), serverEndpoint); + registerRequest.getEndpointName(), sender, serverEndpoint); builder.lwM2mVersion(registerRequest.getLwVersion()).lifeTimeInSec(registerRequest.getLifetime()) .bindingMode(registerRequest.getBindingMode()).objectLinks(registerRequest.getObjectLinks()) @@ -104,8 +104,7 @@ public SendableResponse update(Identity sender, UpdateRequest up } // Create update - final RegistrationUpdate update = new RegistrationUpdate(updateRequest.getRegistrationId(), - sender.getPeerAddress().getAddress(), sender.getPeerAddress().getPort(), + final RegistrationUpdate update = new RegistrationUpdate(updateRequest.getRegistrationId(), sender, updateRequest.getLifeTimeInSec(), updateRequest.getSmsNumber(), updateRequest.getBindingMode(), updateRequest.getObjectLinks()); diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationUpdate.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationUpdate.java index 63a49948f0..674cfed9cf 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationUpdate.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/registration/RegistrationUpdate.java @@ -12,6 +12,7 @@ * * Contributors: * Sierra Wireless - initial API and implementation + * Achim Kraus (Bosch Software Innovations GmbH) - add Identity as destination *******************************************************************************/ package org.eclipse.leshan.server.registration; @@ -21,6 +22,7 @@ import org.eclipse.leshan.Link; import org.eclipse.leshan.core.request.BindingMode; +import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.util.Validate; /** @@ -30,23 +32,18 @@ public class RegistrationUpdate { private final String registrationId; - private final InetAddress address; - private final Integer port; - + private final Identity identity; private final Long lifeTimeInSec; private final String smsNumber; private final BindingMode bindingMode; private final Link[] objectLinks; - public RegistrationUpdate(String registrationId, InetAddress address, Integer port, Long lifeTimeInSec, String smsNumber, + public RegistrationUpdate(String registrationId, Identity identity, Long lifeTimeInSec, String smsNumber, BindingMode bindingMode, Link[] objectLinks) { Validate.notNull(registrationId); - Validate.notNull(address); - Validate.notNull(port); + Validate.notNull(identity); this.registrationId = registrationId; - this.address = address; - this.port = port; - + this.identity = identity; this.lifeTimeInSec = lifeTimeInSec; this.smsNumber = smsNumber; this.bindingMode = bindingMode; @@ -60,8 +57,7 @@ public RegistrationUpdate(String registrationId, InetAddress address, Integer po * @return the updated registration */ public Registration update(Registration registration) { - InetAddress address = this.address != null ? this.address : registration.getAddress(); - int port = this.port != null ? this.port : registration.getPort(); + Identity identity = this.identity != null ? this.identity : registration.getIdentity(); Link[] linkObject = this.objectLinks != null ? this.objectLinks : registration.getObjectLinks(); long lifeTimeInSec = this.lifeTimeInSec != null ? this.lifeTimeInSec : registration.getLifeTimeInSec(); BindingMode bindingMode = this.bindingMode != null ? this.bindingMode : registration.getBindingMode(); @@ -72,7 +68,7 @@ public Registration update(Registration registration) { Date lastUpdate = new Date(); Registration.Builder builder = new Registration.Builder(registration.getId(), registration.getEndpoint(), - address, port, registration.getRegistrationEndpointAddress()); + identity, registration.getRegistrationEndpointAddress()); builder.lwM2mVersion(registration.getLwM2mVersion()).lifeTimeInSec(lifeTimeInSec).smsNumber(smsNumber) .bindingMode(bindingMode).objectLinks(linkObject).registrationDate(registration.getRegistrationDate()) @@ -87,12 +83,16 @@ public String getRegistrationId() { return registrationId; } + public Identity getIdentity() { + return identity; + } + public InetAddress getAddress() { - return address; + return identity.getPeerAddress().getAddress(); } public Integer getPort() { - return port; + return identity.getPeerAddress().getPort(); } public Long getLifeTimeInSec() { @@ -114,19 +114,18 @@ public Link[] getObjectLinks() { @Override public String toString() { return String.format( - "RegistrationUpdate [registrationId=%s, address=%s, port=%s, lifeTimeInSec=%s, smsNumber=%s, bindingMode=%s, objectLinks=%s]", - registrationId, address, port, lifeTimeInSec, smsNumber, bindingMode, Arrays.toString(objectLinks)); + "RegistrationUpdate [registrationId=%s, identity=%s, lifeTimeInSec=%s, smsNumber=%s, bindingMode=%s, objectLinks=%s]", + registrationId, identity, lifeTimeInSec, smsNumber, bindingMode, Arrays.toString(objectLinks)); } @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((address == null) ? 0 : address.hashCode()); result = prime * result + ((bindingMode == null) ? 0 : bindingMode.hashCode()); + result = prime * result + ((identity == null) ? 0 : identity.hashCode()); result = prime * result + ((lifeTimeInSec == null) ? 0 : lifeTimeInSec.hashCode()); result = prime * result + Arrays.hashCode(objectLinks); - result = prime * result + ((port == null) ? 0 : port.hashCode()); result = prime * result + ((registrationId == null) ? 0 : registrationId.hashCode()); result = prime * result + ((smsNumber == null) ? 0 : smsNumber.hashCode()); return result; @@ -141,13 +140,13 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; RegistrationUpdate other = (RegistrationUpdate) obj; - if (address == null) { - if (other.address != null) - return false; - } else if (!address.equals(other.address)) - return false; if (bindingMode != other.bindingMode) return false; + if (identity == null) { + if (other.identity != null) + return false; + } else if (!identity.equals(other.identity)) + return false; if (lifeTimeInSec == null) { if (other.lifeTimeInSec != null) return false; @@ -155,11 +154,6 @@ public boolean equals(Object obj) { return false; if (!Arrays.equals(objectLinks, other.objectLinks)) return false; - if (port == null) { - if (other.port != null) - return false; - } else if (!port.equals(other.port)) - return false; if (registrationId == null) { if (other.registrationId != null) return false; diff --git a/leshan-server-core/src/test/java/org/eclipse/leshan/server/bootstrap/BootstrapHandlerTest.java b/leshan-server-core/src/test/java/org/eclipse/leshan/server/bootstrap/BootstrapHandlerTest.java index 8fcc64eadc..9ec7fcd6ad 100644 --- a/leshan-server-core/src/test/java/org/eclipse/leshan/server/bootstrap/BootstrapHandlerTest.java +++ b/leshan-server-core/src/test/java/org/eclipse/leshan/server/bootstrap/BootstrapHandlerTest.java @@ -108,14 +108,14 @@ public MockRequestSender(boolean success) { } @Override - public T send(String clientEndpoint, InetSocketAddress client, boolean secure, - DownlinkRequest request, long timeout) throws InterruptedException { + public T send(String clientEndpoint, Identity destination, DownlinkRequest request, + long timeout) throws InterruptedException { return null; } @SuppressWarnings("unchecked") @Override - public void send(String clientEndpoint, InetSocketAddress client, boolean secure, + public void send(String clientEndpoint, Identity destination, DownlinkRequest request, long timeout, ResponseCallback responseCallback, ErrorCallback errorCallback) { if (request instanceof BootstrapDeleteRequest) { diff --git a/leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationSortObjectLinksTest.java b/leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationSortObjectLinksTest.java index a3288ba2d3..12321b2b48 100644 --- a/leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationSortObjectLinksTest.java +++ b/leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationSortObjectLinksTest.java @@ -21,6 +21,7 @@ import java.net.UnknownHostException; import org.eclipse.leshan.Link; +import org.eclipse.leshan.core.request.Identity; import org.junit.Assert; import org.junit.Test; @@ -33,8 +34,8 @@ public void sort_link_object_on_get() throws UnknownHostException { objs[1] = new Link("/0/2"); objs[2] = null; - Registration.Builder builder = new Registration.Builder("registrationId", "endpoint", Inet4Address.getByName("127.0.0.1"), - 1, new InetSocketAddress(212)).objectLinks(objs); + Registration.Builder builder = new Registration.Builder("registrationId", "endpoint", + Identity.unsecure(Inet4Address.getLocalHost(), 1), new InetSocketAddress(212)).objectLinks(objs); Registration r = builder.build();