Skip to content

Commit

Permalink
Start to send bootstrap requests after we send bootstrap response.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Jul 19, 2019
1 parent dc1a4c8 commit d3ab4e0
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.leshan.core.request.BootstrapRequest;
import org.eclipse.leshan.core.request.Identity;
import org.eclipse.leshan.core.response.BootstrapResponse;
import org.eclipse.leshan.core.response.SendableResponse;
import org.eclipse.leshan.server.bootstrap.BootstrapHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -79,11 +80,14 @@ public void handlePOST(CoapExchange exchange) {
Identity clientIdentity = EndpointContextUtil.extractIdentity(request.getSourceContext());

// handle bootstrap request
BootstrapResponse response = bootstrapHandler.bootstrap(clientIdentity, new BootstrapRequest(endpoint));
SendableResponse<BootstrapResponse> sendableResponse = bootstrapHandler.bootstrap(clientIdentity,
new BootstrapRequest(endpoint));
BootstrapResponse response = sendableResponse.getResponse();
if (response.isSuccess()) {
exchange.respond(toCoapResponseCode(response.getCode()));
} else {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
}
sendableResponse.sent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
import org.eclipse.leshan.core.request.BootstrapRequest;
import org.eclipse.leshan.core.request.Identity;
import org.eclipse.leshan.core.response.BootstrapResponse;
import org.eclipse.leshan.core.response.SendableResponse;

public interface BootstrapHandler {

BootstrapResponse bootstrap(Identity sender, BootstrapRequest request);
SendableResponse<BootstrapResponse> bootstrap(Identity sender, BootstrapRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.eclipse.leshan.core.response.ErrorCallback;
import org.eclipse.leshan.core.response.LwM2mResponse;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.core.response.SendableResponse;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig.ACLConfig;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig.ServerConfig;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig.ServerSecurity;
Expand Down Expand Up @@ -85,15 +86,15 @@ public DefaultBootstrapHandler(BootstrapConfigStore store, LwM2mBootstrapRequest
}

@Override
public BootstrapResponse bootstrap(Identity sender, BootstrapRequest request) {
public SendableResponse<BootstrapResponse> bootstrap(Identity sender, BootstrapRequest request) {
String endpoint = request.getEndpointName();

// Start session, checking the BS credentials
final BootstrapSession session = this.sessionManager.begin(endpoint, sender);

if (!session.isAuthorized()) {
sessionManager.failed(session, UNAUTHORIZED);
return BootstrapResponse.badRequest("Unauthorized");
return new SendableResponse<>(BootstrapResponse.badRequest("Unauthorized"));
}

// check if there is not an ongoing session.
Expand All @@ -108,7 +109,7 @@ public BootstrapResponse bootstrap(Identity sender, BootstrapRequest request) {
} else {
// Do not start the session if there is already a started one
sessionManager.failed(session, ALREADY_STARTED);
return BootstrapResponse.badRequest("session already started");
return new SendableResponse<>(BootstrapResponse.badRequest("session already started"));
}
}
} while (oldSession != null);
Expand All @@ -119,16 +120,22 @@ public BootstrapResponse bootstrap(Identity sender, BootstrapRequest request) {
if (cfg == null) {
LOG.debug("No bootstrap config for {}", session);
stopSession(session, NO_BOOTSTRAP_CONFIG);
return BootstrapResponse.badRequest("no bootstrap config");
return new SendableResponse<>(BootstrapResponse.badRequest("no bootstrap config"));
}

startBootstrap(session, cfg);
return BootstrapResponse.success();
// Start bootstrap once response is sent.
Runnable onSent = new Runnable() {
@Override
public void run() {
startBootstrap(session, cfg);
}
};
return new SendableResponse<>(BootstrapResponse.success(), onSent);

} catch (RuntimeException e) {
LOG.warn("Unexpected error at bootstrap start-up for {}", session, e);
stopSession(session, INTERNAL_SERVER_ERROR);
return BootstrapResponse.internalServerError(e.getMessage());
return new SendableResponse<>(BootstrapResponse.internalServerError(e.getMessage()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.eclipse.leshan.core.response.ErrorCallback;
import org.eclipse.leshan.core.response.LwM2mResponse;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.core.response.SendableResponse;
import org.eclipse.leshan.server.bootstrap.BootstrapHandlerTest.MockRequestSender.Mode;
import org.eclipse.leshan.server.impl.DefaultBootstrapSession;
import org.junit.Test;
Expand All @@ -47,8 +48,9 @@ public void error_if_not_authorized() {
BootstrapHandler bsHandler = new DefaultBootstrapHandler(null, null, bsSessionManager);

// Try to bootstrap
BootstrapResponse response = bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"),
new BootstrapRequest("endpoint"));
BootstrapResponse response = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"), new BootstrapRequest("endpoint"))
.getResponse();

// Ensure bootstrap session is refused
assertEquals(ResponseCode.BAD_REQUEST, response.getCode());
Expand All @@ -66,7 +68,9 @@ public void bootstrap_success() throws InvalidConfigurationException {
BootstrapHandler bsHandler = new DefaultBootstrapHandler(bsStore, requestSender, bsSessionManager);

// Try to bootstrap
bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"), new BootstrapRequest("endpoint"));
SendableResponse<BootstrapResponse> sendableResponse = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"), new BootstrapRequest("endpoint"));
sendableResponse.sent();

// Ensure bootstrap finished
assertTrue(bsSessionManager.endWasCalled());
Expand All @@ -85,7 +89,9 @@ public void bootstrap_failed_because_of_sent_failure() throws InvalidConfigurati
BootstrapHandler bsHandler = new DefaultBootstrapHandler(bsStore, requestSender, bsSessionManager);

// Try to bootstrap
bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"), new BootstrapRequest("endpoint"));
SendableResponse<BootstrapResponse> sendableResponse = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"), new BootstrapRequest("endpoint"));
sendableResponse.sent();

// Ensure bootstrap failed
assertFalse(bsSessionManager.endWasCalled());
Expand All @@ -108,26 +114,29 @@ public void two_bootstrap_at_the_same_time_not_allowed()
DefaultBootstrapHandler.DEFAULT_TIMEOUT, 1000);

// First bootstrap : which will not end (because of sender)
BootstrapResponse first_response = bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"),
new BootstrapRequest("endpoint"));
SendableResponse<BootstrapResponse> first_response = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4242), "pskdentity"), new BootstrapRequest("endpoint"));
first_response.sent();
// Ensure bootstrap is accepted and not finished
assertTrue(first_response.isSuccess());
assertTrue(first_response.getResponse().isSuccess());
assertFalse(bsSessionManager.endWasCalled());
assertFalse(bsSessionManager.failedWasCalled());

// Second bootstrap for same endpoint : must be refused
bsSessionManager.reset();
BootstrapResponse second_response = bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"),
new BootstrapRequest("endpoint"));
assertTrue(second_response.isFailure());
SendableResponse<BootstrapResponse> second_response = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"), new BootstrapRequest("endpoint"));
second_response.sent();
assertTrue(second_response.getResponse().isFailure());
assertFalse(bsSessionManager.endWasCalled());
assertTrue(bsSessionManager.failedWasCalled());

// Third bootstrap for same endpoint : must be refused
bsSessionManager.reset();
BootstrapResponse third_response = bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"),
new BootstrapRequest("endpoint"));
assertTrue(third_response.isFailure());
SendableResponse<BootstrapResponse> third_response = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"), new BootstrapRequest("endpoint"));
third_response.sent();
assertTrue(third_response.getResponse().isFailure());
assertFalse(bsSessionManager.endWasCalled());
assertTrue(bsSessionManager.failedWasCalled());

Expand All @@ -137,29 +146,32 @@ public void two_bootstrap_at_the_same_time_not_allowed()
// Fourth bootstrap for same endpoint : now it should be accepted
bsSessionManager.reset();
requestSender.setMode(Mode.ALWAYS_SUCCESS);
BootstrapResponse fourth_response = bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"),
new BootstrapRequest("endpoint"));
assertTrue(fourth_response.isSuccess());
SendableResponse<BootstrapResponse> fourth_response = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"), new BootstrapRequest("endpoint"));
fourth_response.sent();
assertTrue(fourth_response.getResponse().isSuccess());
assertTrue(bsSessionManager.endWasCalled());
assertFalse(bsSessionManager.failedWasCalled());

// ensure that after a finished success bootstrap I don't need to wait session lifetime to retry
// fifth bootstrap for same endpoint : it should be accepted too.
bsSessionManager.reset();
requestSender.setMode(Mode.ALWAYS_FAILURE);
BootstrapResponse fifth_response = bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"),
new BootstrapRequest("endpoint"));
assertTrue(fifth_response.isSuccess());
SendableResponse<BootstrapResponse> fifth_response = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"), new BootstrapRequest("endpoint"));
fifth_response.sent();
assertTrue(fifth_response.getResponse().isSuccess());
assertFalse(bsSessionManager.endWasCalled());
assertTrue(bsSessionManager.failedWasCalled());

// ensure that after a failed bootstrap I don't need to wait session lifetime to retry
// sixth bootstrap for same endpoint : it should be accepted too.
bsSessionManager.reset();
requestSender.setMode(Mode.ALWAYS_SUCCESS);
BootstrapResponse sixth_response = bsHandler.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"),
new BootstrapRequest("endpoint"));
assertTrue(sixth_response.isSuccess());
SendableResponse<BootstrapResponse> sixth_response = bsHandler
.bootstrap(Identity.psk(new InetSocketAddress(4243), "pskdentity"), new BootstrapRequest("endpoint"));
sixth_response.sent();
assertTrue(sixth_response.getResponse().isSuccess());
assertTrue(bsSessionManager.endWasCalled());
assertFalse(bsSessionManager.failedWasCalled());
}
Expand Down

0 comments on commit d3ab4e0

Please sign in to comment.