-
Notifications
You must be signed in to change notification settings - Fork 408
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
SenML-CBOR encoder in leshan-core with unit tests #682
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
leshan-core/src/main/java/org/eclipse/leshan/senml/SenMLCbor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/******************************************************************************* | ||
* 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: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
/** | ||
* Helper for encoding/decoding SenML CBOR format | ||
*/ | ||
public class SenMLCbor { | ||
private static final SenMLCborPackSerDes serDes = new SenMLCborPackSerDes(); | ||
|
||
public static byte[] toSenMLCbor(SenMLPack pack) throws SenMLCborException { | ||
return serDes.serializeToCbor(pack); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
leshan-core/src/main/java/org/eclipse/leshan/senml/SenMLCborException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/******************************************************************************* | ||
* 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: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
/** | ||
* Exception thrown in case of Cbor encoding error | ||
*/ | ||
public class SenMLCborException extends Exception { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
public SenMLCborException(String message) { | ||
super(message); | ||
} | ||
|
||
public SenMLCborException(String message, Exception cause) { | ||
super(message, cause); | ||
} | ||
|
||
} |
119 changes: 119 additions & 0 deletions
119
leshan-core/src/main/java/org/eclipse/leshan/senml/SenMLCborPackSerDes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/******************************************************************************* | ||
* 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: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
|
||
import org.eclipse.leshan.core.model.ResourceModel.Type; | ||
|
||
import com.fasterxml.jackson.dataformat.cbor.CBORFactory; | ||
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator; | ||
|
||
public class SenMLCborPackSerDes { | ||
|
||
public byte[] serializeToCbor(SenMLPack pack) throws SenMLCborException { | ||
CBORFactory factory = new CBORFactory(); | ||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
|
||
try { | ||
CBORGenerator generator = factory.createGenerator(out); | ||
generator.writeStartArray(pack.getRecords().size()); | ||
|
||
for (SenMLRecord record : pack.getRecords()) { | ||
boolean hasBaseName = false; | ||
boolean hasBaseTime = false; | ||
boolean hasName = false; | ||
boolean hasTime = false; | ||
int objectSize = 1; | ||
|
||
if (record.getBaseName() != null && !record.getBaseName().isEmpty()) { | ||
hasBaseName = true; | ||
objectSize++; | ||
} | ||
|
||
if (record.getBaseTime() != null) { | ||
hasBaseTime = true; | ||
objectSize++; | ||
} | ||
|
||
if (record.getName() != null && !record.getName().isEmpty()) { | ||
hasName = true; | ||
objectSize++; | ||
} | ||
|
||
if (record.getTime() != null) { | ||
hasTime = true; | ||
objectSize++; | ||
} | ||
|
||
generator.writeStartObject(objectSize); | ||
|
||
if (hasBaseName) { | ||
generator.writeFieldId(-2); | ||
generator.writeString(record.getBaseName()); | ||
} | ||
|
||
if (hasBaseTime) { | ||
generator.writeFieldId(-3); | ||
generator.writeNumber(record.getBaseTime()); | ||
} | ||
|
||
if (hasName) { | ||
generator.writeFieldId(0); | ||
generator.writeString(record.getName()); | ||
} | ||
|
||
if (hasTime) { | ||
generator.writeFieldId(6); | ||
generator.writeNumber(record.getTime()); | ||
} | ||
|
||
Type type = record.getType(); | ||
if (type != null) { | ||
switch (record.getType()) { | ||
case FLOAT: | ||
generator.writeFieldId(2); | ||
generator.writeNumber(record.getFloatValue().intValue()); | ||
break; | ||
case BOOLEAN: | ||
generator.writeFieldId(4); | ||
generator.writeBoolean(record.getBooleanValue()); | ||
break; | ||
case OBJLNK: | ||
generator.writeStringField("vlo", record.getObjectLinkValue()); | ||
break; | ||
case OPAQUE: | ||
generator.writeFieldId(8); | ||
generator.writeBinary(record.getOpaqueValue()); | ||
case STRING: | ||
generator.writeFieldId(3); | ||
generator.writeString(record.getStringValue()); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
generator.writeEndObject(); | ||
} | ||
|
||
generator.writeEndArray(); | ||
generator.close(); | ||
} catch (Exception ex) { | ||
throw new SenMLCborException("Impossible to encode pack to CBOR: \n" + pack, ex); | ||
} | ||
|
||
return out.toByteArray(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
leshan-core/src/test/java/org/eclipse/leshan/senml/AbstractSenMLTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/******************************************************************************* | ||
* 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: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
public abstract class AbstractSenMLTest { | ||
protected void givenResourceWithFloatValue(SenMLPack pack, String n, Number value) { | ||
SenMLRecord elt = new SenMLRecord(); | ||
elt.setName(n); | ||
elt.setFloatValue(value); | ||
pack.addRecord(elt); | ||
} | ||
|
||
protected void givenResourceWithStringValue(SenMLPack pack, String n, String value) { | ||
givenResourceWithStringValue(pack, null, n, value); | ||
} | ||
|
||
protected void givenResourceWithStringValue(SenMLPack pack, String bn, String n, String value) { | ||
SenMLRecord elt = new SenMLRecord(); | ||
if (bn != null) { | ||
elt.setBaseName(bn); | ||
} | ||
|
||
elt.setName(n); | ||
elt.setStringValue(value); | ||
pack.addRecord(elt); | ||
} | ||
|
||
/** | ||
* Example of JSON payload request to Device Object of the LwM2M example client (Read /3/0) | ||
* | ||
* @return JSON payload | ||
*/ | ||
protected String givenSenMLJsonExample() { | ||
StringBuilder b = new StringBuilder(); | ||
b.append("[{\"bn\":\"/3/0/\",\"n\":\"0\",\"vs\":\"Open Mobile Alliance\"},"); | ||
b.append("{\"n\":\"1\",\"vs\":\"Lightweight M2M Client\"},"); | ||
b.append("{\"n\":\"2\",\"vs\":\"345000123\"},"); | ||
b.append("{\"n\":\"3\",\"vs\":\"1.0\"},"); | ||
b.append("{\"n\":\"6/0\",\"v\":1},{\"n\":\"6/1\",\"v\":5},"); | ||
b.append("{\"n\":\"7/0\",\"v\":3800},{\"n\":\"7/1\",\"v\":5000},"); | ||
b.append("{\"n\":\"8/0\",\"v\":125},{\"n\":\"8/1\",\"v\":900},"); | ||
b.append("{\"n\":\"9\",\"v\":100},"); | ||
b.append("{\"n\":\"10\",\"v\":15},"); | ||
b.append("{\"n\":\"11/0\",\"v\":0},"); | ||
b.append("{\"n\":\"13\",\"v\":1.3674912E9},"); | ||
b.append("{\"n\":\"14\",\"vs\":\"+02:00\"},"); | ||
b.append("{\"n\":\"16\",\"vs\":\"U\"}]"); | ||
return b.toString(); | ||
} | ||
|
||
protected SenMLPack givenDeviceObjectInstance() { | ||
SenMLPack pack = new SenMLPack(); | ||
|
||
givenResourceWithStringValue(pack, "/3/0/", "0", "Open Mobile Alliance"); | ||
givenResourceWithStringValue(pack, "1", "Lightweight M2M Client"); | ||
givenResourceWithStringValue(pack, "2", "345000123"); | ||
givenResourceWithStringValue(pack, "3", "1.0"); | ||
|
||
givenResourceWithFloatValue(pack, "6/0", 1); | ||
givenResourceWithFloatValue(pack, "6/1", 5); | ||
givenResourceWithFloatValue(pack, "7/0", 3800); | ||
givenResourceWithFloatValue(pack, "7/1", 5000); | ||
givenResourceWithFloatValue(pack, "8/0", 125); | ||
givenResourceWithFloatValue(pack, "8/1", 900); | ||
|
||
givenResourceWithFloatValue(pack, "9", 100); | ||
givenResourceWithFloatValue(pack, "10", 15); | ||
givenResourceWithFloatValue(pack, "11/0", 0); | ||
givenResourceWithFloatValue(pack, "13", 1367491215l); | ||
|
||
givenResourceWithStringValue(pack, "14", "+02:00"); | ||
givenResourceWithStringValue(pack, "16", "U"); | ||
|
||
return pack; | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
leshan-core/src/test/java/org/eclipse/leshan/senml/SenMLCborSerializerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/******************************************************************************* | ||
* 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: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
import org.eclipse.leshan.util.Hex; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
public class SenMLCborSerializerTest extends AbstractSenMLTest { | ||
|
||
@Test | ||
public void serialize_device_object_to_senml_cbor() throws Exception { | ||
byte[] cbor = SenMLCbor.toSenMLCbor(givenDeviceObjectInstance()); | ||
|
||
String expectedValue = "90a321652f332f302f00613003744f70656e204d6f62696c6520416c6c69616e6365a200613103764c696768747765696768" | ||
+ "74204d324d20436c69656e74a20061320369333435303030313233a20061330363312e30a20063362f300201a20063362f310205a20063372f" | ||
+ "3002190ed8a20063372f3102191388a20063382f3002187da20063382f3102190384a2006139021864a200623130020fa2006431312f300200" | ||
+ "a200623133021a5182428fa20062313403662b30323a3030a200623136036155"; | ||
|
||
Assert.assertTrue(expectedValue.equals(Hex.encodeHexString(cbor))); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Generally, in this project we use "delegation" instead of "inheritance" for reuse code in tests.
But that's not a big deal, if we let it like this :)
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.
I will take care about it.