use of org.eclipse.leshan.senml.SenMLRecord in project leshan by eclipse.
the class AbstractSenMLTest method getPackWithSingleOpaqueValue.
protected SenMLPack getPackWithSingleOpaqueValue(String path, byte[] value) {
SenMLPack pack = new SenMLPack();
SenMLRecord r = new SenMLRecord();
r.setBaseName(path);
r.setOpaqueValue(value);
pack.addRecord(r);
return pack;
}
use of org.eclipse.leshan.senml.SenMLRecord in project leshan by eclipse.
the class LwM2mNodeSenMLDecoder method decodeNodes.
@Override
public Map<LwM2mPath, LwM2mNode> decodeNodes(byte[] content, List<LwM2mPath> paths, LwM2mModel model) throws CodecException {
try {
// Decode SenML pack
SenMLPack pack = decoder.fromSenML(content);
Map<LwM2mPath, LwM2mNode> nodes = new HashMap<>();
if (paths != null) {
// Resolve records & Group it by time-stamp
Map<LwM2mPath, Collection<LwM2mResolvedSenMLRecord>> recordsByPath = groupByPath(pack.getRecords(), paths);
for (LwM2mPath path : paths) {
Collection<LwM2mResolvedSenMLRecord> records = recordsByPath.get(path);
if (records.isEmpty()) {
// Node can be null as the LWM2M specification says that "Read-Composite operation is
// treated as non-atomic and handled as best effort by the client. That is, if any of the
// requested
// resources do not have a valid value to return, they will not be included in the response".
// Meaning that a given path could have no corresponding value.
nodes.put(path, null);
} else {
LwM2mNode node = parseRecords(recordsByPath.get(path), path, model, DefaultLwM2mDecoder.nodeClassFromPath(path));
nodes.put(path, node);
}
}
} else {
// Paths are not given so we given so we can not regroup by path
// let's assume that each path refer to a single resource or single resource instances.
LwM2mSenMLResolver resolver = new LwM2mSenMLResolver();
for (SenMLRecord record : pack.getRecords()) {
LwM2mResolvedSenMLRecord resolvedRecord = resolver.resolve(record);
LwM2mPath path = resolvedRecord.getPath();
LwM2mNode node = parseRecords(Arrays.asList(resolvedRecord), path, model, DefaultLwM2mDecoder.nodeClassFromPath(path));
nodes.put(path, node);
}
}
return nodes;
} catch (SenMLException e) {
String hexValue = content != null ? Hex.encodeHexString(content) : "";
throw new CodecException(e, "Unable to decode nodes[path:%s] : %s", paths, hexValue, e);
}
}
use of org.eclipse.leshan.senml.SenMLRecord in project leshan by eclipse.
the class LwM2mNodeSenMLDecoder method groupByPath.
/**
* Resolved record then group it by LwM2mPath
*/
private Map<LwM2mPath, Collection<LwM2mResolvedSenMLRecord>> groupByPath(List<SenMLRecord> records, List<LwM2mPath> paths) throws SenMLException {
// Prepare map result
Map<LwM2mPath, Collection<LwM2mResolvedSenMLRecord>> result = new HashMap<>(paths.size());
for (LwM2mPath path : paths) {
result.put(path, new ArrayList<LwM2mResolvedSenMLRecord>());
}
// Resolve record and add it to the map
LwM2mSenMLResolver resolver = new LwM2mSenMLResolver();
for (SenMLRecord record : records) {
LwM2mResolvedSenMLRecord resolvedRecord = resolver.resolve(record);
// Find the corresponding path for this record.
LwM2mPath selectedPath = selectPath(resolvedRecord.getPath(), paths);
if (selectedPath == null) {
throw new CodecException("Invalid path [%s] for resource, it should start by one of %s", resolvedRecord.getPath(), paths);
}
result.get(selectedPath).add(resolvedRecord);
}
return result;
}
use of org.eclipse.leshan.senml.SenMLRecord in project leshan by eclipse.
the class LwM2mNodeSenMLDecoder method decodeTimestampedNodes.
@Override
public TimestampedLwM2mNodes decodeTimestampedNodes(byte[] content, LwM2mModel model) throws CodecException {
try {
// Decode SenML pack
SenMLPack pack = decoder.fromSenML(content);
TimestampedLwM2mNodes.Builder nodes = TimestampedLwM2mNodes.builder();
LwM2mSenMLResolver resolver = new LwM2mSenMLResolver();
for (SenMLRecord record : pack.getRecords()) {
LwM2mResolvedSenMLRecord resolvedRecord = resolver.resolve(record);
LwM2mPath path = resolvedRecord.getPath();
LwM2mNode node = parseRecords(Arrays.asList(resolvedRecord), path, model, DefaultLwM2mDecoder.nodeClassFromPath(path));
nodes.put(resolvedRecord.getTimeStamp(), path, node);
}
return nodes.build();
} catch (SenMLException e) {
String hexValue = content != null ? Hex.encodeHexString(content) : "";
throw new CodecException(e, "Unable to decode nodes : %s", hexValue, e);
}
}
use of org.eclipse.leshan.senml.SenMLRecord in project leshan by eclipse.
the class LwM2mNodeSenMLDecoder method decode.
@SuppressWarnings("unchecked")
@Override
public <T extends LwM2mNode> T decode(byte[] content, LwM2mPath path, LwM2mModel model, Class<T> nodeClass) throws CodecException {
try {
// Decode SenML pack
SenMLPack pack = decoder.fromSenML(content);
List<SenMLRecord> records = pack.getRecords();
// Resolve records
LwM2mSenMLResolver resolver = new LwM2mSenMLResolver();
Collection<LwM2mResolvedSenMLRecord> resolvedRecords = new ArrayList<>(records.size());
for (SenMLRecord record : records) {
LwM2mResolvedSenMLRecord resolvedRecord = resolver.resolve(record);
// Validate SenML resolved name
if (!resolvedRecord.getPath().isResourceInstance() && !resolvedRecord.getPath().isResource()) {
throw new CodecException("Invalid path [%s] for resource, it should be a resource or a resource instance path", resolvedRecord.getName());
}
if (!resolvedRecord.getPath().startWith(path)) {
throw new CodecException("Invalid path [%s] for resource, it should start by %s", resolvedRecord.getPath(), path);
}
if (resolvedRecord.getTimeStamp() != null) {
throw new CodecException("Unable to decode node[path:%s] : value should not be timestamped", path);
}
resolvedRecords.add(resolvedRecord);
}
// Parse records and create node
return (T) parseRecords(resolvedRecords, path, model, nodeClass);
} catch (SenMLException e) {
String hexValue = content != null ? Hex.encodeHexString(content) : "";
throw new CodecException(e, "Unable to decode node[path:%s] : %s", path, hexValue, e);
}
}
Aggregations