From b27e954abd9a5de46a4df08406aa1176e61d7dd5 Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Fri, 2 Mar 2018 15:54:31 +0100 Subject: [PATCH] Implemented the update of AdditionalRegistration parameters Signed-off-by: carlosgp143@gmail.com --- .../client/servers/RegistrationEngine.java | 2 +- .../leshan/core/request/UpdateRequest.java | 15 ++++- .../californium/impl/RegisterResource.java | 10 ++- .../impl/InMemoryRegistrationStoreTest.java | 4 +- .../RegistrationUpdateSerDes.java | 16 ++++- .../RegistrationUpdateSerDesTest.java | 5 +- .../registration/RegistrationHandler.java | 2 +- .../registration/RegistrationUpdate.java | 30 ++++++++- .../registration/RegistrationUpdateTest.java | 67 +++++++++++++++++++ 9 files changed, 140 insertions(+), 11 deletions(-) create mode 100644 leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationUpdateTest.java diff --git a/leshan-client-core/src/main/java/org/eclipse/leshan/client/servers/RegistrationEngine.java b/leshan-client-core/src/main/java/org/eclipse/leshan/client/servers/RegistrationEngine.java index 05bba1cf35..e0ed25df0d 100644 --- a/leshan-client-core/src/main/java/org/eclipse/leshan/client/servers/RegistrationEngine.java +++ b/leshan-client-core/src/main/java/org/eclipse/leshan/client/servers/RegistrationEngine.java @@ -250,7 +250,7 @@ private boolean update() throws InterruptedException { // Send update LOG.info("Trying to update registration to {} ...", dmInfo.getFullUri()); UpdateResponse response = sender.send(dmInfo.getAddress(), dmInfo.isSecure(), - new UpdateRequest(registrationID, null, null, null, null), DEFAULT_TIMEOUT); + new UpdateRequest(registrationID, null, null, null, null, null), DEFAULT_TIMEOUT); if (response == null) { registrationID = null; LOG.error("Registration update failed: Timeout."); diff --git a/leshan-core/src/main/java/org/eclipse/leshan/core/request/UpdateRequest.java b/leshan-core/src/main/java/org/eclipse/leshan/core/request/UpdateRequest.java index 99484ace5c..58957fbf78 100644 --- a/leshan-core/src/main/java/org/eclipse/leshan/core/request/UpdateRequest.java +++ b/leshan-core/src/main/java/org/eclipse/leshan/core/request/UpdateRequest.java @@ -15,6 +15,10 @@ *******************************************************************************/ package org.eclipse.leshan.core.request; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.leshan.Link; import org.eclipse.leshan.core.request.exception.InvalidRequestException; import org.eclipse.leshan.core.response.UpdateResponse; @@ -30,6 +34,7 @@ public class UpdateRequest implements UplinkRequest { private final BindingMode bindingMode; private final String registrationId; private final Link[] objectLinks; + private final Map additionalAttributes; /** * Sets all fields. @@ -42,7 +47,7 @@ public class UpdateRequest implements UplinkRequest { * @exception InvalidRequestException if the registrationId is empty. */ public UpdateRequest(String registrationId, Long lifetime, String smsNumber, BindingMode binding, - Link[] objectLinks) throws InvalidRequestException { + Link[] objectLinks, Map additionalAttributes) throws InvalidRequestException { if (registrationId == null || registrationId.isEmpty()) throw new InvalidRequestException("registrationId is mandatory"); @@ -52,6 +57,10 @@ public UpdateRequest(String registrationId, Long lifetime, String smsNumber, Bin this.lifeTimeInSec = lifetime; this.bindingMode = binding; this.smsNumber = smsNumber; + if (additionalAttributes == null) + this.additionalAttributes = Collections.emptyMap(); + else + this.additionalAttributes = Collections.unmodifiableMap(new HashMap<>(additionalAttributes)); } public String getRegistrationId() { @@ -74,6 +83,10 @@ public BindingMode getBindingMode() { return bindingMode; } + public Map getAdditionalAttributes() { + return additionalAttributes; + } + @Override public void accept(UplinkRequestVisitor visitor) { visitor.visit(this); diff --git a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/RegisterResource.java b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/RegisterResource.java index ceaddd533c..d82bb3a78b 100644 --- a/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/RegisterResource.java +++ b/leshan-server-cf/src/main/java/org/eclipse/leshan/server/californium/impl/RegisterResource.java @@ -209,6 +209,8 @@ private void handleUpdate(CoapExchange exchange, Request request, String registr String smsNumber = null; BindingMode binding = null; Link[] objectLinks = null; + Map additionalParams = new HashMap<>(); + for (String param : request.getOptions().getUriQuery()) { if (param.startsWith(QUERY_PARAM_LIFETIME)) { lifetime = Long.valueOf(param.substring(3)); @@ -216,12 +218,18 @@ private void handleUpdate(CoapExchange exchange, Request request, String registr smsNumber = param.substring(4); } else if (param.startsWith(QUERY_PARAM_BINDING_MODE)) { binding = BindingMode.valueOf(param.substring(2)); + } else { + String[] tokens = param.split("\\="); + if (tokens != null && tokens.length == 2) { + additionalParams.put(tokens[0], tokens[1]); + } } } if (request.getPayload() != null && request.getPayload().length > 0) { objectLinks = Link.parse(request.getPayload()); } - UpdateRequest updateRequest = new UpdateRequest(registrationId, lifetime, smsNumber, binding, objectLinks); + UpdateRequest updateRequest = new UpdateRequest(registrationId, lifetime, smsNumber, binding, objectLinks, + additionalParams); // Handle request final SendableResponse sendableResponse = registrationHandler.update(sender, updateRequest); 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 9f575ab7e0..6f75d6ceca 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 @@ -56,7 +56,7 @@ public void update_registration_keeps_properties_unchanged() { store.addRegistration(registration); RegistrationUpdate update = new RegistrationUpdate(registrationId, Identity.unsecure(address, port), null, null, - null, null); + null, null, null); UpdatedRegistration updatedRegistration = store.updateRegistration(update); Assert.assertEquals(lifetime, updatedRegistration.getUpdatedRegistration().getLifeTimeInSec()); Assert.assertSame(binding, updatedRegistration.getUpdatedRegistration().getBindingMode()); @@ -84,7 +84,7 @@ public void update_registration_to_extend_time_to_live() { Assert.assertFalse(registration.isAlive()); RegistrationUpdate update = new RegistrationUpdate(registrationId, Identity.unsecure(address, port), lifetime, - null, null, null); + null, null, null, null); UpdatedRegistration updatedRegistration = store.updateRegistration(update); Assert.assertTrue(updatedRegistration.getUpdatedRegistration().isAlive()); 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 9518bd241f..5e6a5f60b9 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 @@ -69,6 +69,14 @@ public static JsonObject jSerialize(RegistrationUpdate u) { o.add("objLink", links); } + if (u.getAdditionalAttributes() != null) { + JsonObject addAttr = Json.object(); + for (Map.Entry e : u.getAdditionalAttributes().entrySet()) { + addAttr.add(e.getKey(), e.getValue()); + } + o.add("addAttr", addAttr); + } + return o; } @@ -126,6 +134,12 @@ public static RegistrationUpdate deserialize(byte[] data) throws UnknownHostExce } } - return new RegistrationUpdate(regId, identity, lifetime, sms, b, linkObjs); + Map addAttr = new HashMap<>(); + JsonObject o = (JsonObject) v.get("addAttr"); + for (String k : o.names()) { + addAttr.put(k, o.getString(k, "")); + } + + return new RegistrationUpdate(regId, identity, lifetime, sms, b, linkObjs, addAttr); } } \ No newline at end of file diff --git a/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDesTest.java b/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDesTest.java index 488c272f31..1cc323a2d7 100644 --- a/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDesTest.java +++ b/leshan-server-cluster/src/test/java/org/eclipse/leshan/server/cluster/serialization/RegistrationUpdateSerDesTest.java @@ -40,9 +40,12 @@ public void ser_and_des_are_equals() throws Exception { objs[0] = new Link("/0/1024/2", att); objs[1] = new Link("/0/2"); + Map additionalAtt = new HashMap<>(); + additionalAtt.put("at", "5000"); + RegistrationUpdate ru = new RegistrationUpdate("myId", Identity.unsecure(Inet4Address.getByName("127.0.0.1"), LwM2m.DEFAULT_COAP_PORT), 60000l, null, - BindingMode.U, objs); + BindingMode.U, objs, additionalAtt); byte[] ser = RegistrationUpdateSerDes.bSerialize(ru); RegistrationUpdate ru2 = RegistrationUpdateSerDes.deserialize(ser); 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 39543d0b55..25156a667c 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 @@ -106,7 +106,7 @@ public SendableResponse update(Identity sender, UpdateRequest up // Create update final RegistrationUpdate update = new RegistrationUpdate(updateRequest.getRegistrationId(), sender, updateRequest.getLifeTimeInSec(), updateRequest.getSmsNumber(), updateRequest.getBindingMode(), - updateRequest.getObjectLinks()); + updateRequest.getObjectLinks(), updateRequest.getAdditionalAttributes()); // update registration final UpdatedRegistration updatedRegistration = registrationService.getStore().updateRegistration(update); 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 674cfed9cf..474284c314 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 @@ -18,7 +18,10 @@ import java.net.InetAddress; import java.util.Arrays; +import java.util.Collections; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import org.eclipse.leshan.Link; import org.eclipse.leshan.core.request.BindingMode; @@ -37,9 +40,10 @@ public class RegistrationUpdate { private final String smsNumber; private final BindingMode bindingMode; private final Link[] objectLinks; + private final Map additionalAttributes; public RegistrationUpdate(String registrationId, Identity identity, Long lifeTimeInSec, String smsNumber, - BindingMode bindingMode, Link[] objectLinks) { + BindingMode bindingMode, Link[] objectLinks, Map additionalAttributes) { Validate.notNull(registrationId); Validate.notNull(identity); this.registrationId = registrationId; @@ -48,6 +52,10 @@ public RegistrationUpdate(String registrationId, Identity identity, Long lifeTim this.smsNumber = smsNumber; this.bindingMode = bindingMode; this.objectLinks = objectLinks; + if (additionalAttributes == null) + this.additionalAttributes = Collections.emptyMap(); + else + this.additionalAttributes = Collections.unmodifiableMap(new HashMap<>(additionalAttributes)); } /** @@ -63,6 +71,10 @@ public Registration update(Registration registration) { BindingMode bindingMode = this.bindingMode != null ? this.bindingMode : registration.getBindingMode(); String smsNumber = this.smsNumber != null ? this.smsNumber : registration.getSmsNumber(); + Map additionalAttributes = this.additionalAttributes.isEmpty() + ? registration.getAdditionalRegistrationAttributes() + : updateAdditionalAttributes(registration.getAdditionalRegistrationAttributes()); + // this needs to be done in any case, even if no properties have changed, in order // to extend the client registration time-to-live period ... Date lastUpdate = new Date(); @@ -72,8 +84,7 @@ public Registration update(Registration registration) { builder.lwM2mVersion(registration.getLwM2mVersion()).lifeTimeInSec(lifeTimeInSec).smsNumber(smsNumber) .bindingMode(bindingMode).objectLinks(linkObject).registrationDate(registration.getRegistrationDate()) - .lastUpdate(lastUpdate) - .additionalRegistrationAttributes(registration.getAdditionalRegistrationAttributes()); + .lastUpdate(lastUpdate).additionalRegistrationAttributes(additionalAttributes); return builder.build(); @@ -111,6 +122,19 @@ public Link[] getObjectLinks() { return objectLinks; } + public Map getAdditionalAttributes() { + return additionalAttributes; + } + + private Map updateAdditionalAttributes(Map oldAdditionalAttributes) { + + // putAll method updates already present key values or add them if not present. + Map aux = new HashMap(); + aux.putAll(oldAdditionalAttributes); + aux.putAll(this.additionalAttributes); + return aux; + } + @Override public String toString() { return String.format( diff --git a/leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationUpdateTest.java b/leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationUpdateTest.java new file mode 100644 index 0000000000..171e8a9a28 --- /dev/null +++ b/leshan-server-core/src/test/java/org/eclipse/leshan/server/registration/RegistrationUpdateTest.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2017 RISE SICS AB. + * + * 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: + * RISE SICS AB - initial API and implementation + *******************************************************************************/ +package org.eclipse.leshan.server.registration; + +import java.net.Inet4Address; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.leshan.core.request.Identity; +import org.eclipse.leshan.server.queue.PresenceService; +import org.junit.Assert; +import org.junit.Test; + +/** + * tests the implementation of {@link PresenceService} + * + */ +public class RegistrationUpdateTest { + + @Test + public void testAdditionalAttributesUpdate() throws Exception { + Registration.Builder builder = new Registration.Builder("registrationId", "endpoint", + Identity.unsecure(Inet4Address.getLocalHost(), 1), new InetSocketAddress(212)); + + Map additionalAttributes = new HashMap(); + additionalAttributes.put("x", "1"); + additionalAttributes.put("y", "10"); + additionalAttributes.put("z", "100"); + builder.additionalRegistrationAttributes(additionalAttributes); + + Registration r = builder.build(); + + Map updateAdditionalAttributes = new HashMap(); + updateAdditionalAttributes.put("x", "2"); + updateAdditionalAttributes.put("y", "11"); + updateAdditionalAttributes.put("z", "101"); + updateAdditionalAttributes.put("h", "hello"); + + RegistrationUpdate updateReg = new RegistrationUpdate(r.getId(), r.getIdentity(), null, null, null, null, + updateAdditionalAttributes); + + r = updateReg.update(r); + + Map updatedAdditionalAttributes = r.getAdditionalRegistrationAttributes(); + + Assert.assertEquals("2", updatedAdditionalAttributes.get("x")); + Assert.assertEquals("11", updatedAdditionalAttributes.get("y")); + Assert.assertEquals("101", updatedAdditionalAttributes.get("z")); + Assert.assertTrue(updatedAdditionalAttributes.containsKey("h")); + Assert.assertEquals("hello", updatedAdditionalAttributes.get("h")); + + } +} \ No newline at end of file