Skip to content
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

Add an EndpointProvider at Server side for CoAP based on java-coap(fork) #1382

Merged
merged 3 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions build-config/lib-build-config/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ Contributors:
<matcher>java-package</matcher>
<match>/org\.slf4j(\..*)?/</match>
</item>
<item>
<!-- HACK : we exclude com.mbed because of revapi bug.
See : https://github.com/revapi/revapi/issues/186
This should be removed once it will be fixed in revapi. -->
<matcher>java-package</matcher>
<match>/com\.mbed\.coap(\..*)?/</match>
</item>
</exclude>
</elements>
</revapi.filter>
Expand Down
4 changes: 4 additions & 0 deletions leshan-integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Contributors:
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-cf</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-tl-javacoap-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-redis</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public class DeleteTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public class DiscoverTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public class ExecuteTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ public class QueueModeTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,9 @@
package org.eclipse.leshan.integration.tests;

import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.leshan.core.ResponseCode.CONTENT;
import static org.eclipse.leshan.integration.tests.util.LeshanTestClientBuilder.givenClientUsing;
import static org.eclipse.leshan.integration.tests.util.assertion.Assertions.assertArg;
import static org.eclipse.leshan.integration.tests.util.assertion.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
Expand All @@ -41,7 +38,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

Expand All @@ -56,16 +52,10 @@
import org.eclipse.californium.elements.config.UdpConfig;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.link.LinkParseException;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.observation.SingleObservation;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.ObserveRequest;
import org.eclipse.leshan.core.request.ReadRequest;
import org.eclipse.leshan.core.request.exception.RequestCanceledException;
import org.eclipse.leshan.core.request.exception.SendFailedException;
import org.eclipse.leshan.core.response.ErrorCallback;
import org.eclipse.leshan.core.response.ObserveResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.integration.tests.util.LeshanTestClient;
Expand Down Expand Up @@ -98,7 +88,8 @@ public class RegistrationTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down Expand Up @@ -278,54 +269,6 @@ public void register_update_reregister(Protocol protocol, String clientEndpointP
assertThat(client).isRegisteredAt(server);
}

@TestAllTransportLayer
public void register_observe_deregister_observe(Protocol protocol, String clientEndpointProvider,
String serverEndpointProvider) throws NonUniqueSecurityInfoException, InterruptedException {
// TODO java-coap does not raise expected SendFailedException at the end of this tests
// But not sure what should be the right behavior.
// Waiting for https://github.com/open-coap/java-coap/issues/36 before to move forward on this.
assumeTrue(serverEndpointProvider.equals("Californium"));

// Check client is not registered
client = givenClient.build();
assertThat(client).isNotRegisteredAt(server);

// Start it and wait for registration
client.start();
server.waitForNewRegistrationOf(client);
client.waitForRegistrationTo(server);

// Check client is well registered
assertThat(client).isRegisteredAt(server);
Registration registration = server.getRegistrationFor(client);

// observe device timezone
ObserveResponse observeResponse = server.send(registration, new ObserveRequest(3, 0));
assertThat(observeResponse) //
.hasCode(CONTENT) //
.hasValidUnderlyingResponseFor(serverEndpointProvider);

// check observation registry is not null
Set<Observation> observations = server.getObservationService().getObservations(registration);
assertThat(observations) //
.hasSize(1) //
.first().isInstanceOfSatisfying(SingleObservation.class, obs -> {
assertThat(obs.getRegistrationId()).isEqualTo(registration.getId());
assertThat(obs.getPath()).isEqualTo(new LwM2mPath(3, 0));
});

// Check de-registration
client.stop(true);
server.waitForDeregistrationOf(registration, observations);
assertThat(client).isNotRegisteredAt(server);
client.waitForDeregistrationTo(server);
observations = server.getObservationService().getObservations(registration);
assertThat(observations).isEmpty();

// try to send a new observation
assertThrowsExactly(SendFailedException.class, () -> server.send(registration, new ObserveRequest(3, 0), 50));
}

@TestAllTransportLayer
public void register_with_additional_attributes(Protocol protocol, String clientEndpointProvider,
String serverEndpointProvider) throws InterruptedException, LinkParseException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public class CreateFailedTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ static Stream<Arguments> transports() {

Object[][] transports = new Object[][] {
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
{ Protocol.COAP, "Californium", "Californium" } };
{ Protocol.COAP, "Californium", "Californium" }, //
{ Protocol.COAP, "Californium", "java-coap" } };

Object[] contentFormats = new Object[] { //
ContentFormat.TLV, //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
Expand All @@ -46,26 +51,37 @@
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.observation.Observation;
import org.eclipse.leshan.core.request.BindingMode;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.DeregisterRequest;
import org.eclipse.leshan.core.request.ObserveRequest;
import org.eclipse.leshan.core.request.ReadRequest;
import org.eclipse.leshan.core.request.RegisterRequest;
import org.eclipse.leshan.core.request.UpdateRequest;
import org.eclipse.leshan.core.request.exception.SendFailedException;
import org.eclipse.leshan.core.request.exception.TimeoutException;
import org.eclipse.leshan.core.response.ErrorCallback;
import org.eclipse.leshan.core.response.ObserveResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.integration.tests.util.LeshanTestServer;
import org.eclipse.leshan.integration.tests.util.LeshanTestServerBuilder;
import org.eclipse.leshan.integration.tests.util.junit5.extensions.BeforeEachParameterizedResolver;
import org.eclipse.leshan.server.californium.endpoint.ServerProtocolProvider;
import org.eclipse.leshan.server.californium.endpoint.coap.CoapServerProtocolProvider;
import org.eclipse.leshan.server.endpoint.LwM2mServerEndpointsProvider;
import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.transport.javacoap.server.endpoint.JavaCoapServerEndpointsProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import com.mbed.coap.server.CoapServerBuilder;
import com.mbed.coap.transmission.RetransmissionBackOff;

@ExtendWith(BeforeEachParameterizedResolver.class)
public class LockStepTest {
public static final LinkParser linkParser = new DefaultLwM2mLinkParser();
Expand All @@ -82,7 +98,8 @@ public class LockStepTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// Server Endpoint Provider
arguments("Californium"));
arguments("Californium"), //
arguments("java-coap"));
}

/*---------------------------------/
Expand All @@ -97,14 +114,28 @@ protected ServerProtocolProvider getCaliforniumProtocolProvider(Protocol protoco
public void applyDefaultValue(Configuration configuration) {
super.applyDefaultValue(configuration);
// configure retransmission, with this configuration a request without ACK should timeout in
// ~200*5ms
// ~200*5ms = 1s
configuration.set(CoapConfig.ACK_TIMEOUT, 200, TimeUnit.MILLISECONDS) //
.set(CoapConfig.ACK_INIT_RANDOM, 1f) //
.set(CoapConfig.ACK_TIMEOUT_SCALE, 1f) //
.set(CoapConfig.MAX_RETRANSMIT, 4);
}
};
}

@Override
protected LwM2mServerEndpointsProvider getJavaCoapProtocolProvider(Protocol protocol) {
return new JavaCoapServerEndpointsProvider(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) {
@Override
protected CoapServerBuilder createCoapServer() {
return super.createCoapServer()
// configure retransmission, with this configuration a request without ACK should
// timeout in
// 140 + 2*140 + 4*140 = ~1s
.retransmission(RetransmissionBackOff.ofExponential(Duration.ofMillis(140), 2, 1));
}
};
}
};
}

Expand Down Expand Up @@ -329,4 +360,50 @@ public void async_send_with_acknowleged_request_without_response(String givenSer
}));
verify(responseCallback, never()).onResponse(any());
}

@TestAllTransportLayer
public void register_deregister_observe(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());

// deregister client
token = client.sendLwM2mRequest(new DeregisterRequest("rd/" + registration.getId()));
client.expectResponse().token(token).go();
server.waitForDeregistrationOf(registration);

// send read
@SuppressWarnings("unchecked")
ResponseCallback<ObserveResponse> responseCallback = mock(ResponseCallback.class);
ErrorCallback errorCallback = mock(ErrorCallback.class);

server.send(registration, new ObserveRequest(ContentFormat.TEXT_CODE, 3, 0), 500l, responseCallback,
errorCallback);

if (givenServerEndpointProvider.equals("Californium")) {
// with californium endpoint provider "SendFailedException" is raised because,
// we try to add the relation in store before to send the request and registration doesn't exist anymorev
verify(errorCallback, timeout(200).times(1)) //
.onError(assertArg(e -> {
assertThat(e).isInstanceOf(SendFailedException.class);
}));
} else {
// 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();
}

// ensure we don't get answer and there is no observation in store.
verifyNoMoreInteractions(responseCallback, errorCallback);
assertThat(server.getRegistrationService().getAllRegistrations().hasNext() == false);
Set<Observation> observations = server.getObservationService().getObservations(registration);
assertThat(observations).isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public class DynamicIPObserveTest {
static Stream<Arguments> noTlsTransports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"),
arguments(Protocol.COAP, "Californium", "java-coap"));
}

@ParameterizedTest(name = "{0} - Client using {1} - Server using {2}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ public class ObserveCompositeTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public class ObserveServerOnlyTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// Server Endpoint Provider
arguments("Californium"));
arguments("Californium"), //
arguments("java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ public class ObserveTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ static Stream<Arguments> transports() {

Object[][] transports = new Object[][] {
// Server Endpoint Provider
{ "Californium" } };
{ "Californium" }, //
{ "java-coap" } };

Object[] contentFormats = new Object[] { //
ContentFormat.JSON, //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ public class ReadCompositeTest {

static Stream<Arguments> transports() {

Object[][] transports = new Object[][]
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
{ { Protocol.COAP, "Californium", "Californium" } };
Object[][] transports = new Object[][] {
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
{ Protocol.COAP, "Californium", "Californium" }, //
{ Protocol.COAP, "Californium", "java-coap" } };

Object[][] contentFormats = new Object[][] { //
// {request content format, response content format}
Expand Down
Loading