org.eclipse.californium.core.coap.OptionSet Java Examples
The following examples show how to use
org.eclipse.californium.core.coap.OptionSet.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that a number of messages uploaded to Hono's CoAP adapter using TLS_PSK based authentication can be * successfully consumed via the AMQP Messaging Network. * * @param ctx The test context. * @throws InterruptedException if the test fails. */ @Test public void testUploadMessagesUsingPsk(final VertxTestContext ctx) throws InterruptedException { final Tenant tenant = new Tenant(); final VertxTestContext setup = new VertxTestContext(); helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, SECRET) .onComplete(setup.completing()); ctx.verify(() -> assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue()); final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET); testUploadMessages(ctx, tenantId, () -> warmUp(client, createCoapsRequest(Code.POST, getPostResource(), 0)), count -> { final Promise<OptionSet> result = Promise.promise(); final Request request = createCoapsRequest(Code.POST, getPostResource(), count); client.advanced(getHandler(result), request); return result.future(); }); }
Example #2
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
private void assertResponseContainsOneWayCommand( final CoapCommandEndpointConfiguration endpointConfiguration, final OptionSet responseOptions, final String expectedCommand, final String tenantId, final String commandTargetDeviceId) { assertThat(responseOptions.getLocationQuery()) .as("response doesn't contain command") .contains(expectedCommand); assertThat(responseOptions.getContentFormat()).isEqualTo(MediaTypeRegistry.APPLICATION_JSON); assertThat(responseOptions.getLocationPath()).contains(CommandConstants.COMMAND_ENDPOINT, Index.atIndex(0)); if (endpointConfiguration.isSubscribeAsGateway()) { assertThat(responseOptions.getLocationPath()).contains(tenantId, Index.atIndex(1)); assertThat(responseOptions.getLocationPath()).contains(commandTargetDeviceId, Index.atIndex(2)); } }
Example #3
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
private void assertResponseContainsCommand( final CoapCommandEndpointConfiguration endpointConfiguration, final OptionSet responseOptions, final String expectedCommand, final String tenantId, final String commandTargetDeviceId) { assertThat(responseOptions.getLocationQuery()) .as("location query must contain parameter [%s]", expectedCommand) .contains(expectedCommand); assertThat(responseOptions.getContentFormat()).isEqualTo(MediaTypeRegistry.APPLICATION_JSON); int idx = 0; assertThat(responseOptions.getLocationPath()).contains(CommandConstants.COMMAND_RESPONSE_ENDPOINT, Index.atIndex(idx++)); if (endpointConfiguration.isSubscribeAsGateway()) { assertThat(responseOptions.getLocationPath()).contains(tenantId, Index.atIndex(idx++)); assertThat(responseOptions.getLocationPath()).contains(commandTargetDeviceId, Index.atIndex(idx++)); } // request ID assertThat(responseOptions.getLocationPath().get(idx)) .as("location path must contain command request ID") .isNotNull(); }
Example #4
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the CoAP adapter rejects messages from a gateway for a device that it is not authorized for with a * 403. * * @param ctx The test context */ @Test @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) public void testUploadMessageFailsForUnauthorizedGateway(final VertxTestContext ctx) { // GIVEN a device that is connected via gateway "not-the-created-gateway" final Tenant tenant = new Tenant(); final String gatewayId = helper.getRandomDeviceId(tenantId); final Device deviceData = new Device(); deviceData.setVia(Collections.singletonList("not-the-created-gateway")); helper.registry.addPskDeviceForTenant(tenantId, tenant, gatewayId, SECRET) .compose(ok -> helper.registry.registerDevice(tenantId, deviceId, deviceData)) .compose(ok -> { // WHEN another gateway tries to upload a message for the device final Promise<OptionSet> result = Promise.promise(); final CoapClient client = getCoapsClient(gatewayId, tenantId, SECRET); client.advanced(getHandler(result, ResponseCode.FORBIDDEN), createCoapsRequest(Code.PUT, getPutResource(tenantId, deviceId), 0)); return result.future(); }) .onComplete(ctx.completing()); }
Example #5
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the CoAP adapter rejects messages from a disabled gateway * for an enabled device with a 403. * * @param ctx The test context */ @Test @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) public void testUploadMessageFailsForDisabledGateway(final VertxTestContext ctx) { // GIVEN a device that is connected via a disabled gateway final Tenant tenant = new Tenant(); final String gatewayId = helper.getRandomDeviceId(tenantId); final Device gatewayData = new Device(); gatewayData.setEnabled(false); final Device deviceData = new Device(); deviceData.setVia(Collections.singletonList(gatewayId)); helper.registry.addPskDeviceForTenant(tenantId, tenant, gatewayId, gatewayData, SECRET) .compose(ok -> helper.registry.registerDevice(tenantId, deviceId, deviceData)) .compose(ok -> { // WHEN the gateway tries to upload a message for the device final Promise<OptionSet> result = Promise.promise(); final CoapClient client = getCoapsClient(gatewayId, tenantId, SECRET); client.advanced(getHandler(result, ResponseCode.FORBIDDEN), createCoapsRequest(Code.PUT, getPutResource(tenantId, deviceId), 0)); return result.future(); }) .onComplete(ctx.completing()); }
Example #6
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the CoAP adapter rejects messages from a disabled device. * * @param ctx The test context */ @Test @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) public void testUploadMessageFailsForDisabledDevice(final VertxTestContext ctx) { // GIVEN a disabled device final Tenant tenant = new Tenant(); final Device deviceData = new Device(); deviceData.setEnabled(false); helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, deviceData, SECRET) .compose(ok -> { // WHEN the device tries to upload a message final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET); final Promise<OptionSet> result = Promise.promise(); client.advanced(getHandler(result, ResponseCode.NOT_FOUND), createCoapsRequest(Code.POST, getPostResource(), 0)); return result.future(); }) .onComplete(ctx.completing()); }
Example #7
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the CoAP adapter rejects messages from a device that belongs to a tenant for which the CoAP adapter * has been disabled. * * @param ctx The test context */ @Test @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) public void testUploadMessageFailsForDisabledTenant(final VertxTestContext ctx) { // GIVEN a tenant for which the CoAP adapter is disabled final Tenant tenant = new Tenant(); tenant.addAdapterConfig(new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_COAP).setEnabled(false)); helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, SECRET) .compose(ok -> { // WHEN a device that belongs to the tenant uploads a message final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET); final Promise<OptionSet> result = Promise.promise(); client.advanced(getHandler(result, ResponseCode.FORBIDDEN), createCoapsRequest(Code.POST, getPostResource(), 0)); return result.future(); }) .onComplete(ctx.completing()); }
Example #8
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the adapter fails to authenticate a device if the shared key registered * for the device does not match the key used by the device in the DTLS handshake. * * @param ctx The vert.x test context. */ @Test @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) public void testUploadFailsForNonMatchingSharedKey(final VertxTestContext ctx) { final Tenant tenant = new Tenant(); // GIVEN a device for which PSK credentials have been registered helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, "NOT" + SECRET) .compose(ok -> { // WHEN a device tries to upload data and authenticate using the PSK // identity for which the server has a different shared secret on record final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET); final Promise<OptionSet> result = Promise.promise(); client.advanced(getHandler(result), createCoapsRequest(Code.POST, getPostResource(), 0)); return result.future(); }) .onComplete(ctx.failing(t -> { // THEN the request fails because the DTLS handshake cannot be completed assertStatus(ctx, HttpURLConnection.HTTP_UNAVAILABLE, t); ctx.completeNow(); })); }
Example #9
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Gets a handler for CoAP responses. * * @param responseHandler The handler to invoke with the outcome of the request. the handler will be invoked with a * succeeded result if the response contains the expected code. Otherwise it will be invoked with a * result that is failed with a {@link CoapResultException}. * @param expectedStatusCode The status code that is expected in the response. * @return The handler. */ protected final CoapHandler getHandler(final Handler<AsyncResult<OptionSet>> responseHandler, final ResponseCode expectedStatusCode) { return new CoapHandler() { @Override public void onLoad(final CoapResponse response) { if (response.getCode() == expectedStatusCode) { logger.debug("=> received {}", Utils.prettyPrint(response)); responseHandler.handle(Future.succeededFuture(response.getOptions())); } else { logger.warn("expected {} => received {}", expectedStatusCode, Utils.prettyPrint(response)); responseHandler.handle(Future.failedFuture( new CoapResultException(toHttpStatusCode(response.getCode()), response.getResponseText()))); } } @Override public void onError() { responseHandler .handle(Future.failedFuture(new CoapResultException(HttpURLConnection.HTTP_UNAVAILABLE))); } }; }
Example #10
Source File: TelemetryCoapIT.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that a number of telemetry messages uploaded to Hono's CoAP adapter * using QoS 1 can be successfully consumed via the AMQP Messaging Network. * * @param ctx The test context. * @throws InterruptedException if the test fails. */ @Test public void testUploadUsingQoS1(final VertxTestContext ctx) throws InterruptedException { final Tenant tenant = new Tenant(); final VertxTestContext setup = new VertxTestContext(); helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, SECRET) .onComplete(setup.completing()); ctx.verify(() -> assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue()); final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET); testUploadMessages(ctx, tenantId, () -> warmUp(client, createCoapsRequest(Code.POST, Type.CON, getPostResource(), 0)), count -> { final Promise<OptionSet> result = Promise.promise(); final Request request = createCoapsRequest(Code.POST, Type.CON, getPostResource(), count); client.advanced(getHandler(result), request); return result.future(); }); }
Example #11
Source File: TelemetryCoapIT.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that the upload of a telemetry message containing a payload that * exceeds the CoAP adapter's configured max payload size fails with a 4.13 * response code. * * @param ctx The test context. * @throws IOException if the CoAP request cannot be sent to the adapter. * @throws ConnectorException if the CoAP request cannot be sent to the adapter. */ @Test @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) public void testUploadFailsForLargePayload(final VertxTestContext ctx) throws ConnectorException, IOException { final Tenant tenant = new Tenant(); helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, SECRET) .compose(ok -> { final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET); final Request request = createCoapsRequest(Code.POST, Type.CON, getPostResource(), IntegrationTestSupport.getPayload(4096)); final Promise<OptionSet> result = Promise.promise(); client.advanced(getHandler(result, ResponseCode.REQUEST_ENTITY_TOO_LARGE), request); return result.future(); }) .onComplete(ctx.completing()); }
Example #12
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 6 votes |
/** * Verifies that a number of messages uploaded to Hono's CoAP adapter * can be successfully consumed via the AMQP Messaging Network. * * @param ctx The test context. * @throws InterruptedException if the test fails. */ @Test public void testUploadMessagesAnonymously(final VertxTestContext ctx) throws InterruptedException { final Tenant tenant = new Tenant(); final VertxTestContext setup = new VertxTestContext(); helper.registry.addDeviceForTenant(tenantId, tenant, deviceId, SECRET) .onComplete(setup.completing()); ctx.verify(() -> assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue()); final CoapClient client = getCoapClient(); testUploadMessages(ctx, tenantId, () -> warmUp(client, createCoapRequest(Code.PUT, getPutResource(tenantId, deviceId), 0)), count -> { final Promise<OptionSet> result = Promise.promise(); final Request request = createCoapRequest(Code.PUT, getPutResource(tenantId, deviceId), count); client.advanced(getHandler(result), request); return result.future(); }); }
Example #13
Source File: AbstractVertxBasedCoapAdapterTest.java From hono with Eclipse Public License 2.0 | 6 votes |
private static CoapExchange newCoapExchange(final Buffer payload, final Type requestType, final OptionSet options) { final Request request = mock(Request.class); when(request.getType()).thenReturn(requestType); when(request.isConfirmable()).thenReturn(requestType == Type.CON); when(request.getOptions()).thenReturn(options); final Exchange echange = new Exchange(request, Origin.REMOTE, mock(Executor.class)); final CoapExchange coapExchange = mock(CoapExchange.class); when(coapExchange.advanced()).thenReturn(echange); Optional.ofNullable(payload).ifPresent(b -> when(coapExchange.getRequestPayload()).thenReturn(b.getBytes())); when(coapExchange.getRequestOptions()).thenReturn(options); when(coapExchange.getQueryParameter(anyString())).thenAnswer(invocation -> { final String key = invocation.getArgument(0); return options.getUriQuery().stream() .map(param -> param.split("=", 2)) .filter(keyValue -> key.equals(keyValue[0])) .findFirst() .map(keyValue -> keyValue.length < 2 ? Boolean.TRUE.toString() : keyValue[1]) .orElse(null); }); return coapExchange; }
Example #14
Source File: BlockwiseLayer.java From SI with BSD 2-Clause "Simplified" License | 6 votes |
private Request getNextRequestBlock(Request request, BlockwiseStatus status) { int num = status.getCurrentNum(); int szx = status.getCurrentSzx(); Request block = new Request(request.getCode()); // do not enforce CON, since NON could make sense over SMS or similar transports block.setType(request.getType()); block.setDestination(request.getDestination()); block.setDestinationPort(request.getDestinationPort()); // copy options block.setOptions(new OptionSet(request.getOptions())); int currentSize = 1 << (4 + szx); int from = num * currentSize; int to = Math.min((num + 1) * currentSize, request.getPayloadSize()); int length = to - from; byte[] blockPayload = new byte[length]; System.arraycopy(request.getPayload(), from, blockPayload, 0, length); block.setPayload(blockPayload); boolean m = (to < request.getPayloadSize()); block.getOptions().setBlock1(szx, m, num); status.setComplete(!m); return block; }
Example #15
Source File: BlockwiseLayer.java From SI with BSD 2-Clause "Simplified" License | 6 votes |
private Request getNextRequestBlock(Request request, BlockwiseStatus status) { int num = status.getCurrentNum(); int szx = status.getCurrentSzx(); Request block = new Request(request.getCode()); // do not enforce CON, since NON could make sense over SMS or similar transports block.setType(request.getType()); block.setDestination(request.getDestination()); block.setDestinationPort(request.getDestinationPort()); // copy options block.setOptions(new OptionSet(request.getOptions())); int currentSize = 1 << (4 + szx); int from = num * currentSize; int to = Math.min((num + 1) * currentSize, request.getPayloadSize()); int length = to - from; byte[] blockPayload = new byte[length]; System.arraycopy(request.getPayload(), from, blockPayload, 0, length); block.setPayload(blockPayload); boolean m = (to < request.getPayloadSize()); block.getOptions().setBlock1(szx, m, num); status.setComplete(!m); return block; }
Example #16
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that a number of messages uploaded to the CoAP adapter via a gateway * using TLS_PSK can be successfully consumed via the AMQP Messaging Network. * * @param ctx The test context. * @throws InterruptedException if the test fails. */ @Test public void testUploadMessagesViaGateway(final VertxTestContext ctx) throws InterruptedException { // GIVEN a device that is connected via two gateways final Tenant tenant = new Tenant(); final String gatewayOneId = helper.getRandomDeviceId(tenantId); final String gatewayTwoId = helper.getRandomDeviceId(tenantId); final Device deviceData = new Device(); deviceData.setVia(Arrays.asList(gatewayOneId, gatewayTwoId)); final VertxTestContext setup = new VertxTestContext(); helper.registry.addPskDeviceForTenant(tenantId, tenant, gatewayOneId, SECRET) .compose(ok -> helper.registry.addPskDeviceToTenant(tenantId, gatewayTwoId, SECRET)) .compose(ok -> helper.registry.registerDevice(tenantId, deviceId, deviceData)) .onComplete(setup.completing()); ctx.verify(() -> assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue()); final CoapClient gatewayOne = getCoapsClient(gatewayOneId, tenantId, SECRET); final CoapClient gatewayTwo = getCoapsClient(gatewayTwoId, tenantId, SECRET); testUploadMessages(ctx, tenantId, () -> warmUp(gatewayOne, createCoapsRequest(Code.PUT, getPutResource(tenantId, deviceId), 0)), count -> { final CoapClient client = (count.intValue() & 1) == 0 ? gatewayOne : gatewayTwo; final Promise<OptionSet> result = Promise.promise(); final Request request = createCoapsRequest(Code.PUT, getPutResource(tenantId, deviceId), count); client.advanced(getHandler(result), request); return result.future(); }); }
Example #17
Source File: AbstractVertxBasedCoapAdapterTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that the adapter fails the upload of a command response with a 4.03 * if the adapter is disabled for the device's tenant. */ @Test public void testUploadCommandResponseFailsForDisabledTenant() { // GIVEN an adapter that is not enabled for a device's tenant final TenantObject to = TenantObject.from("tenant", true); to.addAdapter(new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_COAP).setEnabled(Boolean.FALSE)); when(tenantClient.get(eq("tenant"), (SpanContext) any())).thenReturn(Future.succeededFuture(to)); final Promise<ProtonDelivery> outcome = Promise.promise(); final CommandResponseSender sender = givenACommandResponseSender(outcome); final CoapServer server = getCoapServer(false); final AbstractVertxBasedCoapAdapter<CoapAdapterProperties> adapter = getAdapter(server, true, null); // WHEN a device publishes an command response final String reqId = Command.getRequestId("correlation", "replyToId", "device"); final Buffer payload = Buffer.buffer("some payload"); final OptionSet options = new OptionSet(); options.addUriPath(CommandConstants.COMMAND_RESPONSE_ENDPOINT).addUriPath(reqId); options.addUriQuery(String.format("%s=%d", Constants.HEADER_COMMAND_RESPONSE_STATUS, 200)); options.setContentFormat(MediaTypeRegistry.TEXT_PLAIN); final CoapExchange coapExchange = newCoapExchange(payload, Type.CON, options); final Device authenticatedDevice = new Device("tenant", "device"); final CoapContext context = CoapContext.fromRequest(coapExchange); adapter.uploadCommandResponseMessage(context, authenticatedDevice, authenticatedDevice); // THEN the command response not been forwarded downstream verify(sender, never()).sendCommandResponse(any(CommandResponse.class), any(SpanContext.class)); // and the device gets a 4.03 response verify(coapExchange).respond(argThat((Response res) -> ResponseCode.FORBIDDEN.equals(res.getCode()))); // and the response has not been reported as forwarded verify(metrics, never()).reportCommand( eq(Direction.RESPONSE), eq("tenant"), any(), eq(ProcessingOutcome.FORWARDED), anyInt(), any()); }
Example #18
Source File: AbstractVertxBasedCoapAdapterTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that the adapter fails the upload of a command response with a 4.00 * response code if it is rejected by the downstream peer. */ @Test public void testUploadCommandResponseFailsForRejectedOutcome() { // GIVEN an adapter with a downstream application attached final Promise<ProtonDelivery> outcome = Promise.promise(); final CommandResponseSender sender = givenACommandResponseSender(outcome); final CoapServer server = getCoapServer(false); final AbstractVertxBasedCoapAdapter<CoapAdapterProperties> adapter = getAdapter(server, true, null); // WHEN a device publishes an command response final String reqId = Command.getRequestId("correlation", "replyToId", "device"); final Buffer payload = Buffer.buffer("some payload"); final OptionSet options = new OptionSet(); options.addUriPath(CommandConstants.COMMAND_RESPONSE_ENDPOINT).addUriPath(reqId); options.addUriQuery(String.format("%s=%d", Constants.HEADER_COMMAND_RESPONSE_STATUS, 200)); options.setContentFormat(MediaTypeRegistry.TEXT_PLAIN); final CoapExchange coapExchange = newCoapExchange(payload, Type.CON, options); final Device authenticatedDevice = new Device("tenant", "device"); final CoapContext context = CoapContext.fromRequest(coapExchange); adapter.uploadCommandResponseMessage(context, authenticatedDevice, authenticatedDevice); outcome.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "malformed message")); // THEN the command response is being forwarded downstream verify(sender).sendCommandResponse(any(CommandResponse.class), any(SpanContext.class)); // and the device gets a 4.00 response verify(coapExchange).respond(argThat((Response res) -> ResponseCode.BAD_REQUEST.equals(res.getCode()))); // and the response has not been reported as forwarded verify(metrics, never()).reportCommand( eq(Direction.RESPONSE), eq("tenant"), any(), eq(ProcessingOutcome.FORWARDED), anyInt(), any()); }
Example #19
Source File: AbstractVertxBasedCoapAdapterTest.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Verifies that the adapter forwards an empty notification downstream. */ @Test public void testUploadEmptyNotificationSucceeds() { // GIVEN an adapter final DownstreamSender sender = givenATelemetrySender(Promise.promise()); final CoapServer server = getCoapServer(false); final AbstractVertxBasedCoapAdapter<CoapAdapterProperties> adapter = getAdapter(server, true, null); // WHEN a device publishes an empty message that is marked as an empty notification final OptionSet options = new OptionSet(); options.addUriQuery(CoapContext.PARAM_EMPTY_CONTENT); final CoapExchange coapExchange = newCoapExchange(null, Type.NON, options); final Device authenticatedDevice = new Device("my-tenant", "the-device"); final CoapContext context = CoapContext.fromRequest(coapExchange); adapter.uploadTelemetryMessage(context, authenticatedDevice, authenticatedDevice); // THEN the device gets a response indicating success verify(coapExchange).respond(argThat((Response res) -> ResponseCode.CHANGED.equals(res.getCode()))); // and the message has been forwarded downstream verify(sender).send(argThat(msg -> EventConstants.isEmptyNotificationType(msg.getContentType())), any(SpanContext.class)); verify(metrics).reportTelemetry( eq(MetricsTags.EndpointType.TELEMETRY), eq("my-tenant"), any(), eq(MetricsTags.ProcessingOutcome.FORWARDED), eq(MetricsTags.QoS.AT_MOST_ONCE), eq(0), eq(TtdStatus.NONE), any()); }
Example #20
Source File: AbstractVertxBasedCoapAdapter.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Adds a command to a CoAP response. * <p> * This default implementation adds the command name, content format and response URI to the * CoAP response options and puts the command's input data (if any) to the response body. * * @param response The CoAP response. * @param commandContext The context containing the command to add. * @param currentSpan The Open Tracing span used for tracking the CoAP request. */ protected void addCommandToResponse( final Response response, final CommandContext commandContext, final Span currentSpan) { final Command command = commandContext.getCommand(); final OptionSet options = response.getOptions(); options.addLocationQuery(Constants.HEADER_COMMAND + "=" + command.getName()); if (command.isOneWay()) { options.setLocationPath(CommandConstants.COMMAND_ENDPOINT); } else { options.setLocationPath(CommandConstants.COMMAND_RESPONSE_ENDPOINT); } currentSpan.setTag(Constants.HEADER_COMMAND, command.getName()); log.debug("adding command [name: {}, request-id: {}] to response for device [tenant-id: {}, device-id: {}]", command.getName(), command.getRequestId(), command.getTenant(), command.getDeviceId()); commandContext.getCurrentSpan().log("forwarding command to device in CoAP response"); if (command.isTargetedAtGateway()) { options.addLocationPath(command.getTenant()); options.addLocationPath(command.getOriginalDeviceId()); currentSpan.setTag(Constants.HEADER_COMMAND_TARGET_DEVICE, command.getOriginalDeviceId()); } if (!command.isOneWay()) { options.addLocationPath(command.getRequestId()); currentSpan.setTag(Constants.HEADER_COMMAND_REQUEST_ID, command.getRequestId()); } final int formatCode = MediaTypeRegistry.parse(command.getContentType()); if (formatCode != MediaTypeRegistry.UNDEFINED) { options.setContentFormat(formatCode); } else { currentSpan.log("ignoring unknown content type [" + command.getContentType() + "] of command"); } Optional.ofNullable(command.getPayload()).ifPresent(b -> response.setPayload(b.getBytes())); }
Example #21
Source File: CoapOptionInjectExtractAdapter.java From hono with Eclipse Public License 2.0 | 5 votes |
/** * Creates a new carrier for extracting a trace context from CoAP options. * * @param options The CoAP options to extract the context from. * @throws NullPointerException if options is {@code null}. * @return The carrier to use for extraction. */ public static Optional<CoapOptionInjectExtractAdapter> forExtraction(final OptionSet options) { Objects.requireNonNull(options); return getTraceContextOption(options) .map(option -> { final CoapOptionInjectExtractAdapter adapter = new CoapOptionInjectExtractAdapter(); adapter.optionToExtractFrom = option; return Optional.of(adapter); }) .orElse(Optional.empty()); }
Example #22
Source File: CoAPWrapper.java From gsn with GNU General Public License v3.0 | 4 votes |
@Override public void onLoad(CoapResponse response) { OptionSet os = response.getOptions(); nextExpectedMessage = os.getMaxAge() * 2 + (System.currentTimeMillis() / 1000); postStreamElement(new Serializable[]{response.getPayload()}); }
Example #23
Source File: CoapMessage.java From SI with BSD 2-Clause "Simplified" License | 4 votes |
private CoapMessage(boolean incoming, Type type, int mId, String token, OptionSet options, byte[] payload) { this.incoming = incoming; this.timestamp = System.currentTimeMillis(); this.type = type.toString(); this.mId = mId; this.token = token; if (options != null) { List<Option> opts = options.asSortedList(); if (!opts.isEmpty()) { Map<String, List<String>> optMap = new HashMap<>(); for (Option opt : opts) { String strOption = OptionNumberRegistry.toString(opt.getNumber()); List<String> values = optMap.get(strOption); if (values == null) { values = new ArrayList<>(); optMap.put(strOption, values); } values.add(opt.toValueString()); } StringBuilder builder = new StringBuilder(); for (Entry<String, List<String>> e : optMap.entrySet()) { if (builder.length() > 0) { builder.append(" - "); } builder.append(e.getKey()).append(": ").append(StringUtils.join(e.getValue(), ", ")); } this.options = builder.toString(); } } if (payload != null && payload.length > 0) { String strPayload = new String(payload, Charsets.UTF_8); if (StringUtils.isAsciiPrintable(strPayload)) { this.payload = strPayload; } else { this.payload = "Hex:" + Hex.encodeHexString(payload); } } }
Example #24
Source File: CoapMessage.java From SI with BSD 2-Clause "Simplified" License | 4 votes |
private CoapMessage(boolean incoming, Type type, int mId, String token, OptionSet options, byte[] payload) { this.incoming = incoming; this.timestamp = System.currentTimeMillis(); this.type = type.toString(); this.mId = mId; this.token = token; if (options != null) { List<Option> opts = options.asSortedList(); if (!opts.isEmpty()) { Map<String, List<String>> optMap = new HashMap<>(); for (Option opt : opts) { String strOption = OptionNumberRegistry.toString(opt.getNumber()); List<String> values = optMap.get(strOption); if (values == null) { values = new ArrayList<>(); optMap.put(strOption, values); } values.add(opt.toValueString()); } StringBuilder builder = new StringBuilder(); for (Entry<String, List<String>> e : optMap.entrySet()) { if (builder.length() > 0) { builder.append(" - "); } builder.append(e.getKey()).append(": ").append(StringUtils.join(e.getValue(), ", ")); } this.options = builder.toString(); } } if (payload != null && payload.length > 0) { String strPayload = new String(payload, Charsets.UTF_8); if (StringUtils.isAsciiPrintable(strPayload)) { this.payload = strPayload; } else { this.payload = "Hex:" + Hex.encodeHexString(payload); } } }
Example #25
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 4 votes |
/** * Verifies that the CoAP adapter delivers a one-way command to a device. * * @param endpointConfig The endpoints to use for sending/receiving commands. * @param ctx The test context * @throws InterruptedException if the test fails. */ @ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN) @MethodSource("commandAndControlVariants") @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) public void testUploadMessagesWithTtdThatReplyWithOneWayCommand( final CoapCommandEndpointConfiguration endpointConfig, final VertxTestContext ctx) throws InterruptedException { final Tenant tenant = new Tenant(); final String expectedCommand = String.format("%s=%s", Constants.HEADER_COMMAND, COMMAND_TO_SEND); final VertxTestContext setup = new VertxTestContext(); helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, SECRET).onComplete(setup.completing()); ctx.verify(() -> assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue()); final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET); final AtomicInteger counter = new AtomicInteger(); final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId; final String subscribingDeviceId = endpointConfig.isSubscribeAsGatewayForSingleDevice() ? commandTargetDeviceId : deviceId; testUploadMessages(ctx, tenantId, () -> warmUp(client, createCoapsRequest(Code.POST, getPostResource(), 0)), msg -> { final Integer ttd = MessageHelper.getTimeUntilDisconnect(msg); logger.debug("north-bound-cmd received {}, ttd: {}", msg, ttd); TimeUntilDisconnectNotification.fromMessage(msg).ifPresent(notification -> { ctx.verify(() -> { assertThat(notification.getTenantId()).isEqualTo(tenantId); assertThat(notification.getDeviceId()).isEqualTo(subscribingDeviceId); }); logger.debug("send one-way-command"); final JsonObject inputData = new JsonObject().put(COMMAND_JSON_KEY, (int) (Math.random() * 100)); helper.sendOneWayCommand( tenantId, commandTargetDeviceId, COMMAND_TO_SEND, "application/json", inputData.toBuffer(), // set "forceCommandRerouting" message property so that half the command are rerouted via the AMQP network IntegrationTestSupport.newCommandMessageProperties(() -> counter.getAndIncrement() >= MESSAGES_TO_SEND / 2), notification.getMillisecondsUntilExpiry() / 2); }); }, count -> { final Promise<OptionSet> result = Promise.promise(); final Request request = createCoapsRequest(endpointConfig, commandTargetDeviceId, count); request.getOptions().addUriQuery(String.format("%s=%d", Constants.HEADER_TIME_TILL_DISCONNECT, 4)); logger.debug("south-bound send {}", request); client.advanced(getHandler(result, ResponseCode.CHANGED), request); return result.future() .map(responseOptions -> { ctx.verify(() -> { assertResponseContainsOneWayCommand( endpointConfig, responseOptions, expectedCommand, tenantId, commandTargetDeviceId); }); return responseOptions; }); }); }
Example #26
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 4 votes |
/** * Uploads messages to the CoAP endpoint. * * @param ctx The test context to run on. * @param tenantId The tenant that the device belongs to. * @param warmUp A sender of messages used to warm up the adapter before running the test itself or {@code null} if * no warm up should be performed. * @param messageConsumer Consumer that is invoked when a message was received. * @param requestSender The test device that will publish the data. * @param numberOfMessages The number of messages that are uploaded. * @throws InterruptedException if the test is interrupted before it has finished. */ protected void testUploadMessages( final VertxTestContext ctx, final String tenantId, final Supplier<Future<?>> warmUp, final Consumer<Message> messageConsumer, final Function<Integer, Future<OptionSet>> requestSender, final int numberOfMessages) throws InterruptedException { final CountDownLatch received = new CountDownLatch(numberOfMessages); final VertxTestContext setup = new VertxTestContext(); createConsumer(tenantId, msg -> { logger.trace("received {}", msg); assertMessageProperties(ctx, msg); if (messageConsumer != null) { messageConsumer.accept(msg); } received.countDown(); if (received.getCount() % 20 == 0) { logger.info("messages received: {}", numberOfMessages - received.getCount()); } }) .compose(ok -> Optional.ofNullable(warmUp).map(w -> w.get()).orElse(Future.succeededFuture())) .onComplete(setup.completing()); ctx.verify(() -> assertThat(setup.awaitCompletion(5, TimeUnit.SECONDS)).isTrue()); final long start = System.currentTimeMillis(); final AtomicInteger messageCount = new AtomicInteger(0); while (messageCount.get() < numberOfMessages) { final CountDownLatch sending = new CountDownLatch(1); requestSender.apply(messageCount.getAndIncrement()).compose(this::assertCoapResponse) .onComplete(attempt -> { if (attempt.succeeded()) { logger.debug("sent message {}", messageCount.get()); } else { logger.info("failed to send message {}: {}", messageCount.get(), attempt.cause().getMessage()); ctx.failNow(attempt.cause()); } sending.countDown();; }); if (messageCount.get() % 20 == 0) { logger.info("messages sent: {}", messageCount.get()); } sending.await(); } final long timeToWait = Math.max(TEST_TIMEOUT_MILLIS - 1000, Math.round(numberOfMessages * 20)); if (received.await(timeToWait, TimeUnit.MILLISECONDS)) { logger.info("sent {} and received {} messages after {} milliseconds", messageCount, numberOfMessages - received.getCount(), System.currentTimeMillis() - start); ctx.completeNow(); } else { logger.info("sent {} and received {} messages after {} milliseconds", messageCount, numberOfMessages - received.getCount(), System.currentTimeMillis() - start); ctx.failNow(new AssertionError("did not receive all messages sent")); } }
Example #27
Source File: AbstractVertxBasedCoapAdapterTest.java From hono with Eclipse Public License 2.0 | 4 votes |
private static CoapExchange newCoapExchange(final Buffer payload, final Type requestType, final Integer contentFormat) { final OptionSet options = new OptionSet(); Optional.ofNullable(contentFormat).ifPresent(options::setContentFormat); return newCoapExchange(payload, requestType, options); }
Example #28
Source File: AbstractVertxBasedCoapAdapterTest.java From hono with Eclipse Public License 2.0 | 4 votes |
/** * Verifies that the adapter waits for a command response being settled and accepted * by a downstream peer before responding with a 2.04 status to the device. */ @Test public void testUploadCommandResponseWaitsForAcceptedOutcome() { // GIVEN an adapter with a downstream application attached final Promise<ProtonDelivery> outcome = Promise.promise(); final CommandResponseSender sender = givenACommandResponseSender(outcome); final CoapServer server = getCoapServer(false); final AbstractVertxBasedCoapAdapter<CoapAdapterProperties> adapter = getAdapter(server, true, null); // WHEN a device publishes an command response final String reqId = Command.getRequestId("correlation", "replyToId", "device"); final Buffer payload = Buffer.buffer("some payload"); final OptionSet options = new OptionSet(); options.addUriPath(CommandConstants.COMMAND_RESPONSE_ENDPOINT).addUriPath(reqId); options.addUriQuery(String.format("%s=%d", Constants.HEADER_COMMAND_RESPONSE_STATUS, 200)); options.setContentFormat(MediaTypeRegistry.TEXT_PLAIN); final CoapExchange coapExchange = newCoapExchange(payload, Type.CON, options); final Device authenticatedDevice = new Device("tenant", "device"); final CoapContext context = CoapContext.fromRequest(coapExchange); adapter.uploadCommandResponseMessage(context, authenticatedDevice, authenticatedDevice); // THEN the command response is being forwarded downstream verify(sender).sendCommandResponse(any(CommandResponse.class), any(SpanContext.class)); // but the device does not get a response verify(coapExchange, never()).respond(any(Response.class)); // and the response has not been reported as forwarded verify(metrics, never()).reportCommand( eq(Direction.RESPONSE), eq("tenant"), any(), eq(ProcessingOutcome.FORWARDED), anyInt(), any()); // until the message has been accepted outcome.complete(mock(ProtonDelivery.class)); verify(coapExchange).respond(argThat((Response res) -> ResponseCode.CHANGED.equals(res.getCode()))); verify(metrics).reportCommand( eq(Direction.RESPONSE), eq("tenant"), any(), eq(ProcessingOutcome.FORWARDED), eq(payload.length()), any()); }
Example #29
Source File: TracingSupportingHonoResource.java From hono with Eclipse Public License 2.0 | 4 votes |
private SpanContext extractSpanContextFromRequest(final OptionSet requestOptions) { return CoapOptionInjectExtractAdapter.forExtraction(requestOptions) .map(carrier -> tracer.extract(Format.Builtin.BINARY, carrier)) .orElse(null); }
Example #30
Source File: CoapTestBase.java From hono with Eclipse Public License 2.0 | 3 votes |
/** * Uploads messages to the CoAP endpoint. * * @param ctx The test context to run on. * @param tenantId The tenant that the device belongs to. * @param messageConsumer Consumer that is invoked when a message was received. * @param warmUp A sender of messages used to warm up the adapter before * running the test itself or {@code null} if no warm up should * be performed. * @param requestSender The test device that will publish the data. * @throws InterruptedException if the test is interrupted before it * has finished. */ protected void testUploadMessages( final VertxTestContext ctx, final String tenantId, final Supplier<Future<?>> warmUp, final Consumer<Message> messageConsumer, final Function<Integer, Future<OptionSet>> requestSender) throws InterruptedException { testUploadMessages(ctx, tenantId, warmUp, messageConsumer, requestSender, MESSAGES_TO_SEND); }