-
Notifications
You must be signed in to change notification settings - Fork 407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
read composite on root path #1520
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,4 +28,6 @@ public interface LwM2mNodeVisitor { | |
|
||
void visit(LwM2mResourceInstance instance); | ||
|
||
default void visit(LwM2mRoot root) { | ||
} | ||
Comment on lines
+31
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure we should add a default visit. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2013-2015 Sierra Wireless and others. | ||
* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* and Eclipse Distribution License v1.0 which accompany this distribution. | ||
* | ||
* The Eclipse Public License is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* and the Eclipse Distribution License is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.html. | ||
* | ||
* Contributors: | ||
* Orange Polska S.A. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.leshan.core.node; | ||
|
||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class LwM2mRoot implements LwM2mNode { | ||
private final Map<Integer, LwM2mObject> objects; | ||
|
||
public LwM2mRoot(Collection<LwM2mObject> objects) { | ||
LwM2mNodeUtil.validateNotNull(objects, "objects MUST NOT be null"); | ||
HashMap<Integer, LwM2mObject> objectsMap = new HashMap<>(objects.size()); | ||
for (LwM2mObject object : objects) { | ||
LwM2mObject previous = objectsMap.put(object.getId(), object); | ||
if (previous != null) { | ||
throw new LwM2mNodeException( | ||
"Unable to create LwM2mRoot : there are several objects with the same id %d", object.getId()); | ||
} | ||
} | ||
this.objects = Collections.unmodifiableMap(objectsMap); | ||
} | ||
|
||
@Override | ||
public int getId() { | ||
return 0; | ||
} | ||
|
||
@Override | ||
public void accept(LwM2mNodeVisitor visitor) { | ||
// TODO: visitors currently don't support a visit from LwM2mRoot | ||
visitor.visit(this); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure to get this TODO ? |
||
} | ||
|
||
@Override | ||
public String toPrettyString(LwM2mPath path) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public StringBuilder appendPrettyNode(StringBuilder b, LwM2mPath path) { | ||
return null; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be implemented. |
||
|
||
public Map<Integer, LwM2mObject> getObjects() { | ||
return objects; | ||
} | ||
|
||
// TODO: add compare and other stuff that a LwM2m node should have | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep this should probably added. (See #1504 maybe this could help) |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ | |
import org.eclipse.leshan.core.node.LwM2mPath; | ||
import org.eclipse.leshan.core.node.LwM2mResource; | ||
import org.eclipse.leshan.core.node.LwM2mResourceInstance; | ||
import org.eclipse.leshan.core.node.LwM2mRoot; | ||
import org.eclipse.leshan.core.node.ObjectLink; | ||
import org.eclipse.leshan.core.node.TimestampedLwM2mNode; | ||
import org.eclipse.leshan.core.node.TimestampedLwM2mNodes; | ||
|
@@ -200,14 +201,34 @@ public byte[] encodeTimestampedNodes(TimestampedLwM2mNodes timestampedNodes, LwM | |
|
||
private class InternalEncoder implements LwM2mNodeVisitor { | ||
// visitor inputs | ||
private int objectId; | ||
private Integer objectId; | ||
private LwM2mModel model; | ||
private LwM2mPath requestPath; | ||
private LwM2mValueConverter converter; | ||
|
||
// visitor output | ||
private ArrayList<SenMLRecord> records = new ArrayList<>(); | ||
|
||
@Override | ||
public void visit(LwM2mRoot root) { | ||
LOG.trace("Encoding Root into SenML"); | ||
// Validate request path | ||
if (!requestPath.isRoot()) { | ||
throw new CodecException("Invalid request path %s for root encoding", requestPath); | ||
} | ||
|
||
// Create SenML records | ||
for (LwM2mObject object : root.getObjects().values()) { | ||
for (LwM2mObjectInstance instance : object.getInstances().values()) { | ||
for (LwM2mResource resource : instance.getResources().values()) { | ||
String prefixPath = object.getId() + "/" + instance.getId() + "/" + resource.getId(); | ||
this.objectId = object.getId(); | ||
lwM2mResourceToSenMLRecord(prefixPath, resource); | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void visit(LwM2mObject object) { | ||
LOG.trace("Encoding Object {} into SenML", object); | ||
|
@@ -302,7 +323,7 @@ private void addSenMLRecord(String recordName, Type valueType, Type expectedType | |
String n = recordName == null ? "" : recordName; | ||
|
||
// Add slash if necessary | ||
if (!n.isEmpty()) { | ||
if (!n.isEmpty() && !bn.equals("/")) { | ||
bn += "/"; | ||
Comment on lines
+328
to
329
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds strange I need to look at this deeper. |
||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,12 +23,17 @@ | |
|
||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.stream.Stream; | ||
|
||
import org.eclipse.leshan.core.endpoint.Protocol; | ||
import org.eclipse.leshan.core.model.ResourceModel.Type; | ||
import org.eclipse.leshan.core.node.LwM2mObject; | ||
import org.eclipse.leshan.core.node.LwM2mResource; | ||
import org.eclipse.leshan.core.node.LwM2mResourceInstance; | ||
import org.eclipse.leshan.core.node.LwM2mRoot; | ||
import org.eclipse.leshan.core.node.LwM2mSingleResource; | ||
import org.eclipse.leshan.core.request.ContentFormat; | ||
import org.eclipse.leshan.core.request.ReadCompositeRequest; | ||
|
@@ -107,6 +112,110 @@ public void stop() throws InterruptedException { | |
/*---------------------------------/ | ||
* Tests | ||
* -------------------------------*/ | ||
|
||
@TestAllCases | ||
public void can_read_root(ContentFormat requestContentFormat, ContentFormat responseContentFormat, | ||
Protocol givenProtocol, String givenClientEndpointProvider, String givenServerEndpointProvider) | ||
throws InterruptedException { | ||
// read root object | ||
ReadCompositeResponse response = server.send(currentRegistration, | ||
new ReadCompositeRequest(requestContentFormat, responseContentFormat, "/")); | ||
|
||
// verify result | ||
// assertEquals(CONTENT, response.getCode()); | ||
// assertContentFormat(responseContentFormat, response); | ||
Comment on lines
+132
to
+134
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be removed ? |
||
|
||
assertThat(response) // | ||
.hasCode(CONTENT) // | ||
.hasCode(response.getCode()).hasContentFormat(responseContentFormat, givenServerEndpointProvider); | ||
|
||
LwM2mRoot root = (LwM2mRoot) response.getContent("/"); | ||
Set<Integer> objectIdsFromRootObject = root.getObjects().keySet(); | ||
Set<Integer> objectIdsFromObjectTree = new HashSet<>(Arrays.asList(1, 3, 3442)); | ||
|
||
// assertEquals(objectIdsFromObjectTree, objectIdsFromRootObject); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be removed ? |
||
assertThat(objectIdsFromObjectTree).isEqualTo(objectIdsFromRootObject); | ||
|
||
} | ||
|
||
@TestAllCases | ||
public void can_read_root_single_resource(ContentFormat requestContentFormat, ContentFormat responseContentFormat, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure to understand why there is several test where all do a ReadComposite on A possible way to test it could be to :
(This will work if no value change between 2 call, if some change let me know) |
||
Protocol givenProtocol, String givenClientEndpointProvider, String givenServerEndpointProvider) | ||
throws InterruptedException { | ||
// read device model number | ||
ReadCompositeResponse response = server.send(currentRegistration, | ||
new ReadCompositeRequest(requestContentFormat, responseContentFormat, "/")); | ||
|
||
// verify result | ||
assertThat(response) // | ||
.hasCode(CONTENT) // | ||
.hasContentFormat(responseContentFormat, givenServerEndpointProvider); | ||
|
||
LwM2mRoot root = (LwM2mRoot) response.getContent("/"); | ||
LwM2mResource resource1 = root.getObjects().get(1).getInstance(0).getResource(1); | ||
assertThat(resource1.getId()).isEqualTo(1); | ||
assertThat(resource1.getValue()).isEqualTo(300L); | ||
assertThat(resource1.getType()).isEqualTo(Type.INTEGER); | ||
|
||
LwM2mResource resource110 = root.getObjects().get(3442).getInstance(0).getResource(110); | ||
assertThat(resource110.getId()).isEqualTo(110); | ||
assertThat(resource110.getValue()).isEqualTo("initial value"); | ||
assertThat(resource110.getType()).isEqualTo(Type.STRING); | ||
|
||
LwM2mResource resource0 = root.getObjects().get(3).getInstance(0).getResource(0); | ||
assertThat(resource0.getId()).isEqualTo(0); | ||
assertThat(resource0.getValue()).isEqualTo("Eclipse Leshan"); | ||
assertThat(resource0.getType()).isEqualTo(Type.STRING); | ||
} | ||
|
||
@TestAllCases | ||
public void can_read_root_multiple_resource(ContentFormat requestContentFormat, ContentFormat responseContentFormat, | ||
Protocol givenProtocol, String givenClientEndpointProvider, String givenServerEndpointProvider) | ||
throws InterruptedException { | ||
// read device model number | ||
ReadCompositeResponse response = server.send(currentRegistration, | ||
new ReadCompositeRequest(requestContentFormat, responseContentFormat, "/")); | ||
|
||
// verify result | ||
assertThat(response) // | ||
.hasCode(CONTENT) // | ||
.hasContentFormat(responseContentFormat, givenServerEndpointProvider); | ||
|
||
LwM2mRoot root = (LwM2mRoot) response.getContent("/"); | ||
LwM2mResource resource = root.getObjects().get(3442).getInstance(0).getResource(1140); | ||
|
||
LwM2mResourceInstance instance = resource.getInstance(0); | ||
assertThat(instance.getId()).isEqualTo(0); | ||
assertThat(instance.getValue()).isEqualTo(true); | ||
assertThat(instance.getType()).isEqualTo(Type.BOOLEAN); | ||
} | ||
|
||
@TestAllCases | ||
public void can_read_root_single_and_multiple_resource(ContentFormat requestContentFormat, | ||
ContentFormat responseContentFormat, Protocol givenProtocol, String givenClientEndpointProvider, | ||
String givenServerEndpointProvider) throws InterruptedException { | ||
// read device model number | ||
ReadCompositeResponse response = server.send(currentRegistration, | ||
new ReadCompositeRequest(requestContentFormat, responseContentFormat, "/")); | ||
|
||
// verify result | ||
assertThat(response) // | ||
.hasCode(CONTENT) // | ||
.hasContentFormat(responseContentFormat, givenServerEndpointProvider); | ||
|
||
LwM2mRoot root = (LwM2mRoot) response.getContent("/"); | ||
|
||
LwM2mResource resource = root.getObjects().get(3442).getInstance(0).getResource(1120); | ||
assertThat(resource.getId()).isEqualTo(1120); | ||
assertThat(resource.getType()).isEqualTo(Type.INTEGER); | ||
|
||
LwM2mResourceInstance instance = resource.getInstance(0); | ||
assertThat(instance.getId()).isEqualTo(0); | ||
assertThat(instance.getValue()).isEqualTo(1024L); | ||
assertThat(instance.getType()).isEqualTo(Type.INTEGER); | ||
} | ||
|
||
|
||
@TestAllCases | ||
public void can_read_resources(ContentFormat requestContentFormat, ContentFormat responseContentFormat, | ||
Protocol givenProtocol, String givenClientEndpointProvider, String givenServerEndpointProvider) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep I think some check should be done here.
The spec says :
(http://www.openmobilealliance.org/release/LightweightM2M/V1_1_1-20190617-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_1_1-20190617-A.html#6-3-8-0-638-Read-Composite-Operation)
So I think on failure, we should not stop the read-composite operation but just log as error.
(so error will not be seen at server side)