Skip to content

Commit

Permalink
Read response
Browse files Browse the repository at this point in the history
  • Loading branch information
mgdlkundera committed Apr 19, 2024
1 parent 089f2da commit 1ea4b47
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ public ErrorResponseCreator(ResponseCode code, String errorMessage) {

@Override
public void visit(ReadRequest request) {
response = new ReadResponse(code, null, errorMessage);
response = new ReadResponse(code, null, null, errorMessage);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ public ObserveResponse(ResponseCode code, LwM2mNode content, List<TimestampedLwM

public ObserveResponse(ResponseCode code, LwM2mNode content, List<TimestampedLwM2mNode> timestampedValues,
SingleObservation observation, String errorMessage, Object coapResponse) {
super(code, timestampedValues != null && !timestampedValues.isEmpty() ? timestampedValues.get(0).getNode()
: content, errorMessage, coapResponse);
super(code, content,
timestampedValues != null && !timestampedValues.isEmpty() ? timestampedValues.get(0) : null,
errorMessage, coapResponse);

// CHANGED is out of spec but is supported for backward compatibility. (previous draft version)
if (ResponseCode.CHANGED.equals(code)) {
Expand All @@ -53,7 +54,7 @@ public ObserveResponse(ResponseCode code, LwM2mNode content, List<TimestampedLwM
this.timestampedValues = timestampedValues;
}

public List<TimestampedLwM2mNode> getTimestampedLwM2mNode() {
public List<TimestampedLwM2mNode> getTimestampedLwM2mNodes() {
return timestampedValues;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,27 @@
import org.eclipse.leshan.core.node.LwM2mNode;
import org.eclipse.leshan.core.node.LwM2mSingleResource;
import org.eclipse.leshan.core.node.ObjectLink;
import org.eclipse.leshan.core.node.TimestampedLwM2mNode;
import org.eclipse.leshan.core.request.exception.InvalidResponseException;
import org.eclipse.leshan.core.util.datatype.ULong;

public class ReadResponse extends AbstractLwM2mResponse {

protected final LwM2mChildNode content;

public ReadResponse(ResponseCode code, LwM2mNode content, String errorMessage) {
this(code, content, errorMessage, null);
protected final TimestampedLwM2mNode timestampedValue;

public ReadResponse(ResponseCode code, LwM2mNode content, TimestampedLwM2mNode timestampedValue,
String errorMessage) {
this(code, content, timestampedValue, errorMessage, null);
}

public ReadResponse(ResponseCode code, LwM2mNode content, String errorMessage, Object coapResponse) {
public ReadResponse(ResponseCode code, LwM2mNode content, TimestampedLwM2mNode timestampedValue,
String errorMessage, Object coapResponse) {
super(code, errorMessage, coapResponse);

content = timestampedValue != null ? timestampedValue.getNode() : content;

if (ResponseCode.CONTENT.equals(code)) {
if (content == null)
throw new InvalidResponseException("Content is mandatory for successful response");
Expand All @@ -48,6 +55,11 @@ public ReadResponse(ResponseCode code, LwM2mNode content, String errorMessage, O
content.getClass().getSimpleName());
}
this.content = (LwM2mChildNode) content;
this.timestampedValue = timestampedValue;
}

public TimestampedLwM2mNode getTimestampedLwM2mNode() {
return timestampedValue;
}

@Override
Expand Down Expand Up @@ -94,65 +106,76 @@ public static ReadResponse success(LwM2mNode content) {
return new ReadResponse(ResponseCode.CONTENT, content, null, null);
}

public static ReadResponse success(TimestampedLwM2mNode timestampedValue) {
return new ReadResponse(ResponseCode.CONTENT, null, timestampedValue, null, null);
}

public static ReadResponse success(int resourceId, String value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newStringResource(resourceId, value), null);
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newStringResource(resourceId, value), null,
null);
}

public static ReadResponse success(int resourceId, Date value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newDateResource(resourceId, value), null);
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newDateResource(resourceId, value), null,
null);
}

public static ReadResponse success(int resourceId, long value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newIntegerResource(resourceId, value), null);
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newIntegerResource(resourceId, value), null,
null);
}

public static ReadResponse success(int resourceId, ULong value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newUnsignedIntegerResource(resourceId, value),
null);
null, null);
}

public static ReadResponse success(int resourceId, ObjectLink value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newObjectLinkResource(resourceId, value),
null);
null, null);
}

public static ReadResponse success(int resourceId, double value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newFloatResource(resourceId, value), null);
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newFloatResource(resourceId, value), null,
null);
}

public static ReadResponse success(int resourceId, boolean value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newBooleanResource(resourceId, value), null);
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newBooleanResource(resourceId, value), null,
null);
}

public static ReadResponse success(int resourceId, byte[] value) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newBinaryResource(resourceId, value), null);
return new ReadResponse(ResponseCode.CONTENT, LwM2mSingleResource.newBinaryResource(resourceId, value), null,
null);
}

public static ReadResponse success(int resourceId, Map<Integer, ?> value, Type type) {
return new ReadResponse(ResponseCode.CONTENT, LwM2mMultipleResource.newResource(resourceId, value, type), null);
return new ReadResponse(ResponseCode.CONTENT, LwM2mMultipleResource.newResource(resourceId, value, type), null,
null);
}

public static ReadResponse notFound() {
return new ReadResponse(ResponseCode.NOT_FOUND, null, null);
return new ReadResponse(ResponseCode.NOT_FOUND, null, null, null);
}

public static ReadResponse unauthorized() {
return new ReadResponse(ResponseCode.UNAUTHORIZED, null, null);
return new ReadResponse(ResponseCode.UNAUTHORIZED, null, null, null);
}

public static ReadResponse methodNotAllowed() {
return new ReadResponse(ResponseCode.METHOD_NOT_ALLOWED, null, null);
return new ReadResponse(ResponseCode.METHOD_NOT_ALLOWED, null, null, null);
}

public static ReadResponse notAcceptable() {
return new ReadResponse(ResponseCode.NOT_ACCEPTABLE, null, null);
return new ReadResponse(ResponseCode.NOT_ACCEPTABLE, null, null, null);
}

public static ReadResponse badRequest(String errorMessage) {
return new ReadResponse(ResponseCode.BAD_REQUEST, null, errorMessage);
return new ReadResponse(ResponseCode.BAD_REQUEST, null, null, errorMessage);
}

public static ReadResponse internalServerError(String errorMessage) {
return new ReadResponse(ResponseCode.INTERNAL_SERVER_ERROR, null, errorMessage);
return new ReadResponse(ResponseCode.INTERNAL_SERVER_ERROR, null, null, errorMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void should_not_throw_exception_if_has_content(ResponseCode responseCode)

// then
assertEquals(exampleResource, response.getContent());
assertNull(response.getTimestampedLwM2mNode());
assertNull(response.getTimestampedLwM2mNodes());
}

@TestAllResponseCode
Expand All @@ -91,6 +91,6 @@ public void should_get_content_from_first_of_timestamped_values(ResponseCode res

// then
assertEquals(timestampedValues.get(0).getNode(), response.getContent());
assertEquals(timestampedValues, response.getTimestampedLwM2mNode());
assertEquals(timestampedValues, response.getTimestampedLwM2mNodes());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,8 @@ public Token sendCoapRequest(Request coapReq) {
public String getEndpointName() {
return endpointName;
}

public LwM2mModel getLwM2mModel() {
return model;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.net.InetSocketAddress;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.Callable;
Expand All @@ -54,6 +55,11 @@
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.link.LinkParser;
import org.eclipse.leshan.core.link.lwm2m.DefaultLwM2mLinkParser;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.node.LwM2mSingleResource;
import org.eclipse.leshan.core.node.TimestampedLwM2mNodes;
import org.eclipse.leshan.core.node.codec.DefaultLwM2mEncoder;
import org.eclipse.leshan.core.node.codec.LwM2mEncoder;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.request.BindingMode;
import org.eclipse.leshan.core.request.ContentFormat;
Expand Down Expand Up @@ -315,7 +321,7 @@ public ReadResponse call() throws Exception {

// Acknowledge the response
client.expectRequest().storeMID("R").go();
client.sendEmpty(Type.ACK).loadMID("R").go();
client.sendEmpty(Type.ACK, ContentFormat.TEXT).loadMID("R").go();

// Request should timedout in ~3s as we send the ACK
Thread.sleep(1500);
Expand Down Expand Up @@ -370,7 +376,7 @@ public void async_send_with_acknowleged_request_without_response(String givenSer

// Acknowledge the response
client.expectRequest().storeMID("R").go();
client.sendEmpty(Type.ACK).loadMID("R").go();
client.sendEmpty(Type.ACK, ContentFormat.TEXT).loadMID("R").go();

// Request should timedout in ~3s as we send a ack
Thread.sleep(1500);
Expand Down Expand Up @@ -418,8 +424,8 @@ public void register_deregister_observe(String givenServerEndpointProvider) thro
// with java-coap it failed transparently at response reception.
// TODO I don't know if this is the right behavior.
client.expectRequest().storeMID("R").storeToken("T").go();
client.sendResponse(Type.ACK, ResponseCode.CONTENT).payload("aaa").observe(2).loadMID("R").loadToken("T")
.go();
client.sendResponse(Type.ACK, ResponseCode.CONTENT, ContentFormat.TEXT).payload("aaa").observe(2)
.loadMID("R").loadToken("T").go();
}

// ensure we don't get answer and there is no observation in store.
Expand All @@ -428,4 +434,47 @@ public void register_deregister_observe(String givenServerEndpointProvider) thro
Set<Observation> observations = server.getObservationService().getObservations(registration);
assertThat(observations).isEmpty();
}

@TestAllTransportLayer
public void read_timestamped(String givenServerEndpointProvider) throws Exception {

// -------------------------------------------REGISTER
// CLIENT----------------------------------------------------
LockStepLwM2mClient client = new LockStepLwM2mClient(server.getEndpoint(Protocol.COAP).getURI());
Token token = client
.sendLwM2mRequest(new RegisterRequest(client.getEndpointName(), 60l, "1.1", EnumSet.of(BindingMode.U),
null, null, linkParser.parseCoreLinkFormat("</1>,</2>,</3>".getBytes()), null));
client.expectResponse().token(token).go();
server.waitForNewRegistrationOf(client.getEndpointName());
Registration registration = server.getRegistrationService().getByEndpoint(client.getEndpointName());
// --------------------------------------------------------------------------------------------------------------

// ----------------------------------------------TIMESTAMP-------------------------------------------------------
LwM2mEncoder encoder = new DefaultLwM2mEncoder();
TimestampedLwM2mNodes.Builder builder = new TimestampedLwM2mNodes.Builder();
Instant t1 = Instant.now();
builder.put(t1, new LwM2mPath("/1/0/1"), LwM2mSingleResource.newIntegerResource(1, 3600));
TimestampedLwM2mNodes timestampedNodes = builder.build();
byte[] payload = encoder.encodeTimestampedNodes(timestampedNodes, ContentFormat.SENML_JSON,
client.getLwM2mModel());
// --------------------------------------------------------------------------------------------------------------

// Send read REQUEST
Future<ReadResponse> future = Executors.newSingleThreadExecutor().submit(new Callable<ReadResponse>() {
@Override
public ReadResponse call() throws Exception {
// send a request with 3 seconds timeout
return server.send(registration, new ReadRequest(ContentFormat.SENML_JSON, 1), 2000);
}
});

client.expectRequest().storeToken("TKN").storeMID("MID").go();

client.sendResponse(Type.ACK, ResponseCode.CONTENT, ContentFormat.SENML_JSON).loadMID("MID").loadToken("TKN")
.payload(payload).go();

ReadResponse response = future.get(2000, TimeUnit.MILLISECONDS);
assertThat(response.getTimestampedLwM2mNode()).isNotNull();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public void can_observe_timestamped_resource(ContentFormat contentFormat, String
ObserveResponse response = server.waitForNotificationOf(observation);
assertThat(response).hasContentFormat(contentFormat, givenServerEndpointProvider);
assertThat(response.getContent()).isEqualTo(mostRecentNode.getNode());
assertThat(response.getTimestampedLwM2mNode()).isEqualTo(timestampedNodes);
assertThat(response.getTimestampedLwM2mNodes()).isEqualTo(timestampedNodes);
}

@TestAllCases
Expand Down Expand Up @@ -194,7 +194,7 @@ public void can_observe_timestamped_instance(ContentFormat contentFormat, String
ObserveResponse response = server.waitForNotificationOf(observation);
assertThat(response).hasContentFormat(contentFormat, givenServerEndpointProvider);
assertThat(response.getContent()).isEqualTo(mostRecentNode.getNode());
assertThat(response.getTimestampedLwM2mNode()).isEqualTo(timestampedNodes);
assertThat(response.getTimestampedLwM2mNodes()).isEqualTo(timestampedNodes);
}

@TestAllCases
Expand Down Expand Up @@ -235,6 +235,6 @@ public void can_observe_timestamped_object(ContentFormat contentFormat, String g
ObserveResponse response = server.waitForNotificationOf(observation);
assertThat(response).hasContentFormat(contentFormat, givenServerEndpointProvider);
assertThat(response.getContent()).isEqualTo(mostRecentNode.getNode());
assertThat(response.getTimestampedLwM2mNode()).isEqualTo(timestampedNodes);
assertThat(response.getTimestampedLwM2mNodes()).isEqualTo(timestampedNodes);
}
}
Loading

0 comments on commit 1ea4b47

Please sign in to comment.