org.eclipse.californium.core.coap.CoAP.ResponseCode Java Examples

The following examples show how to use org.eclipse.californium.core.coap.CoAP.ResponseCode. 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: CoapResource.java    From SI with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Remove all observe relations to CoAP clients and notify them that the
 * observe relation has been canceled.
 * 
 * @param code
 *            the error code why the relation was terminated
 *            (e.g., 4.04 after deletion)
 */
public void clearAndNotifyObserveRelations(ResponseCode code) {
	/*
	 * draft-ietf-core-observe-08, chapter 3.2 Notification states:
	 * In the event that the resource changes in a way that would cause
	 * a normal GET request at that time to return a non-2.xx response
	 * (for example, when the resource is deleted), the server sends a
	 * notification with a matching response code and removes the client
	 * from the list of observers.
	 * This method is called, when the resource is deleted.
	 */
	for (ObserveRelation relation:observeRelations) {
		relation.cancel();
		relation.getExchange().sendResponse(new Response(code));
	}
}
 
Example #2
Source File: CoapErrorResponse.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Gets a CoAP response code for an error.
 *
 * @param cause The cause of the error.
 * @param defaultCode The default CoAP response code to use if the error cannot be mapped.
 * @return The CoAP response code.
 */
public static ResponseCode toCoapCode(final Throwable cause, final ResponseCode defaultCode) {

    if (ServiceInvocationException.class.isInstance(cause)) {
        final int statusCode = ((ServiceInvocationException) cause).getErrorCode();

        final int codeClass = statusCode / 100;
        final int codeDetail = statusCode % 100;
        if (0 < codeClass && codeClass < 8 && 0 <= codeDetail && codeDetail < 32) {
            try {
                return ResponseCode.valueOf(codeClass << 5 | codeDetail);
            } catch (MessageFormatException e) {
                // ignore
            }
        }
    }
    return defaultCode;
}
 
Example #3
Source File: CoapResource.java    From SI with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Remove all observe relations to CoAP clients and notify them that the
 * observe relation has been canceled.
 * 
 * @param code
 *            the error code why the relation was terminated
 *            (e.g., 4.04 after deletion)
 */
public void clearAndNotifyObserveRelations(ResponseCode code) {
	/*
	 * draft-ietf-core-observe-08, chapter 3.2 Notification states:
	 * In the event that the resource changes in a way that would cause
	 * a normal GET request at that time to return a non-2.xx response
	 * (for example, when the resource is deleted), the server sends a
	 * notification with a matching response code and removes the client
	 * from the list of observers.
	 * This method is called, when the resource is deleted.
	 */
	for (ObserveRelation relation:observeRelations) {
		relation.cancel();
		relation.getExchange().sendResponse(new Response(code));
	}
}
 
Example #4
Source File: CoapErrorResponse.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Create response with the provide error cause.
 *
 * @param cause error cause
 * @param defaultCode default response code, if a more specific response code is not available.
 * @return The CoAP response.
 */
public static Response respond(final Throwable cause, final ResponseCode defaultCode) {

    final String message = cause == null ? null : cause.getMessage();
    final ResponseCode code = toCoapCode(cause, defaultCode);
    final Response response = respond(message, code);
    switch (code) {
    case SERVICE_UNAVAILABLE:
        // delay retry by 2 seconds, see http adapter, HttpUtils.serviceUnavailable(ctx, 2)
        response.getOptions().setMaxAge(2);
        break;
    default:
        break;
    }
    return response;
}
 
Example #5
Source File: ServerMessageDeliverer.java    From SI with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public void deliverRequest(final Exchange exchange) {
	Request request = exchange.getRequest();
	List<String> path = request.getOptions().getUriPath();
	final Resource resource = findResource(path);
	if (resource != null) {
		checkForObserveOption(exchange, resource);
		
		// Get the executor and let it process the request
		Executor executor = resource.getExecutor();
		if (executor != null) {
			exchange.setCustomExecutor();
			executor.execute(new Runnable() {
				public void run() {
					resource.handleRequest(exchange);
				} });
		} else {
			resource.handleRequest(exchange);
		}
	} else {
		LOGGER.info("Did not find resource " + path.toString() + " requested by " + request.getSource()+":"+request.getSourcePort());
		exchange.sendResponse(new Response(ResponseCode.NOT_FOUND));
	}
}
 
Example #6
Source File: CoapResource.java    From SI with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * This method is used to apply resource-specific knowledge on the exchange.
 * If the request was successful, it sets the Observe option for the
 * response. It is important to use the notificationOrderer of the resource
 * here. Further down the layer, race conditions could cause local
 * reordering of notifications. If the response has an error code, no
 * observe relation can be established and if there was one previously it is
 * canceled. When this resource allows to be observed by clients and the
 * request is a GET request with an observe option, the
 * {@link ServerMessageDeliverer} already created the relation, as it
 * manages the observing endpoints globally.
 * 
 * @param exchange the exchange
 * @param response the response
 */
public void checkObserveRelation(Exchange exchange, Response response) {
	/*
	 * If the request for the specified exchange tries to establish an observer
	 * relation, then the ServerMessageDeliverer must have created such a relation
	 * and added to the exchange. Otherwise, there is no such relation.
	 * Remember that different paths might lead to this resource.
	 */
	
	ObserveRelation relation = exchange.getRelation();
	if (relation == null) return; // because request did not try to establish a relation
	
	if (CoAP.ResponseCode.isSuccess(response.getCode())) {
		response.getOptions().setObserve(notificationOrderer.getCurrent());
		
		if (!relation.isEstablished()) {
			relation.setEstablished(true);
			addObserveRelation(relation);
		} else if (observeType != null) {
			// The resource can control the message type of the notification
			response.setType(observeType);
		}
	} // ObserveLayer takes care of the else case
}
 
Example #7
Source File: CoapTestBase.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * 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 vote down vote up
/**
 * 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 #9
Source File: CoapTransportResource.java    From iotplatform with Apache License 2.0 6 votes vote down vote up
@Override
public void handlePOST(CoapExchange exchange) {
  Optional<FeatureType> featureType = getFeatureType(exchange.advanced().getRequest());
  if (!featureType.isPresent()) {
    log.trace("Missing feature type parameter");
    exchange.respond(ResponseCode.BAD_REQUEST);
  } else {
    switch (featureType.get()) {
    case ATTRIBUTES:
      processRequest(exchange, MsgType.POST_ATTRIBUTES_REQUEST);
      break;
    case TELEMETRY:
      processRequest(exchange, MsgType.POST_TELEMETRY_REQUEST);
      break;
    case RPC:
      Optional<Integer> requestId = getRequestId(exchange.advanced().getRequest());
      if (requestId.isPresent()) {
        processRequest(exchange, MsgType.TO_DEVICE_RPC_RESPONSE);
      } else {
        processRequest(exchange, MsgType.TO_SERVER_RPC_REQUEST);
      }
      break;
    }
  }
}
 
Example #10
Source File: CoapResource.java    From SI with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * This method is used to apply resource-specific knowledge on the exchange.
 * If the request was successful, it sets the Observe option for the
 * response. It is important to use the notificationOrderer of the resource
 * here. Further down the layer, race conditions could cause local
 * reordering of notifications. If the response has an error code, no
 * observe relation can be established and if there was one previously it is
 * canceled. When this resource allows to be observed by clients and the
 * request is a GET request with an observe option, the
 * {@link ServerMessageDeliverer} already created the relation, as it
 * manages the observing endpoints globally.
 * 
 * @param exchange the exchange
 * @param response the response
 */
public void checkObserveRelation(Exchange exchange, Response response) {
	/*
	 * If the request for the specified exchange tries to establish an observer
	 * relation, then the ServerMessageDeliverer must have created such a relation
	 * and added to the exchange. Otherwise, there is no such relation.
	 * Remember that different paths might lead to this resource.
	 */
	
	ObserveRelation relation = exchange.getRelation();
	if (relation == null) return; // because request did not try to establish a relation
	
	if (CoAP.ResponseCode.isSuccess(response.getCode())) {
		response.getOptions().setObserve(notificationOrderer.getCurrent());
		
		if (!relation.isEstablished()) {
			relation.setEstablished(true);
			addObserveRelation(relation);
		} else if (observeType != null) {
			// The resource can control the message type of the notification
			response.setType(observeType);
		}
	} // ObserveLayer takes care of the else case
}
 
Example #11
Source File: ServerMessageDeliverer.java    From SI with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public void deliverRequest(final Exchange exchange) {
	Request request = exchange.getRequest();
	List<String> path = request.getOptions().getUriPath();
	final Resource resource = findResource(path);
	if (resource != null) {
		checkForObserveOption(exchange, resource);
		
		// Get the executor and let it process the request
		Executor executor = resource.getExecutor();
		if (executor != null) {
			exchange.setCustomExecutor();
			executor.execute(new Runnable() {
				public void run() {
					resource.handleRequest(exchange);
				} });
		} else {
			resource.handleRequest(exchange);
		}
	} else {
		LOGGER.info("Did not find resource " + path.toString() + " requested by " + request.getSource()+":"+request.getSourcePort());
		exchange.sendResponse(new Response(ResponseCode.NOT_FOUND));
	}
}
 
Example #12
Source File: TelemetryCoapIT.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * 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 #13
Source File: CoapTestBase.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * 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 #14
Source File: CoapTestBase.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * 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 #15
Source File: AbstractVertxBasedCoapAdapter.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Forwards the body of a CoAP request to the south bound Telemetry API of the AMQP 1.0 Messaging Network.
 *
 * @param context The context representing the request to be processed.
 * @param authenticatedDevice authenticated device
 * @param originDevice message's origin device
 * @return A future containing the response code that has been returned to
 *         the device.
 * @throws NullPointerException if any of the parameters is {@code null}.
 */
public final Future<ResponseCode> uploadTelemetryMessage(
        final CoapContext context,
        final Device authenticatedDevice,
        final Device originDevice) {

    return doUploadMessage(
            Objects.requireNonNull(context),
            Objects.requireNonNull(authenticatedDevice),
            Objects.requireNonNull(originDevice),
            context.isConfirmable(),
            getTelemetrySender(authenticatedDevice.getTenantId()),
            MetricsTags.EndpointType.TELEMETRY);
}
 
Example #16
Source File: CoapResource.java    From SI with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Delete this resource from its parents and notify all observing CoAP
 * clients that this resource is no longer accessible.
 */
public synchronized void delete() {
	Resource parent = getParent();
	if (parent != null) {
		parent.delete(this);
	}
	
	if (isObservable()) {
		clearAndNotifyObserveRelations(ResponseCode.NOT_FOUND);
	}
}
 
Example #17
Source File: TracingSupportingHonoResourceTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Sets up the fixture.
 */
@BeforeEach
public void setUp() {
    final Span span = mock(Span.class);
    spanBuilder = mock(SpanBuilder.class, RETURNS_SELF);
    when(spanBuilder.start()).thenReturn(span);
    tracer = mock(Tracer.class);
    when(tracer.buildSpan(anyString())).thenReturn(spanBuilder);
    resource = new TracingSupportingHonoResource(tracer, "test", "adapter") {
        @Override
        protected Future<ResponseCode> handlePost(final CoapExchange exchange, final Span currentSpan) {
            return Future.succeededFuture(ResponseCode.CHANGED);
        }
    };
}
 
Example #18
Source File: AbstractVertxBasedCoapAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * 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 #19
Source File: AbstractVertxBasedCoapAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the adapter fails the upload of an event with a 4.00 result
 * if the request body is not empty but doesn't contain a content-format option.
 */
@Test
public void testUploadTelemetryFailsForMissingContentFormat() {

    // 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 a non-empty message that lacks a content-format option
    final Buffer payload = Buffer.buffer("some payload");
    final CoapExchange coapExchange = newCoapExchange(payload, Type.NON, (Integer) null);
    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 with code 4.00
    verify(coapExchange).respond(argThat((Response res) -> ResponseCode.BAD_REQUEST.equals(res.getCode())));

    // and the message has not been forwarded downstream
    verify(sender, never()).send(any(Message.class), any(SpanContext.class));
    verify(metrics, never()).reportTelemetry(
            any(MetricsTags.EndpointType.class),
            anyString(),
            any(),
            any(MetricsTags.ProcessingOutcome.class),
            any(MetricsTags.QoS.class),
            anyInt(),
            any(TtdStatus.class),
            any());
}
 
Example #20
Source File: AbstractVertxBasedCoapAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the adapter fails the upload of an event with a 4.00 result
 * if the request body is empty but is not marked as an empty notification.
 */
@Test
public void testUploadTelemetryFailsForEmptyBody() {

    // 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 doesn't contain
    // a URI-query option
    final CoapExchange coapExchange = newCoapExchange(null, Type.NON, MediaTypeRegistry.UNDEFINED);
    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 with code 4.00
    verify(coapExchange).respond(argThat((Response res) -> ResponseCode.BAD_REQUEST.equals(res.getCode())));

    // and the message has not been forwarded downstream
    verify(sender, never()).send(any(Message.class), any(SpanContext.class));
    verify(metrics, never()).reportTelemetry(
            any(MetricsTags.EndpointType.class),
            anyString(),
            any(),
            any(MetricsTags.ProcessingOutcome.class),
            any(MetricsTags.QoS.class),
            anyInt(),
            any(TtdStatus.class),
            any());
}
 
Example #21
Source File: AbstractVertxBasedCoapAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * 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 #22
Source File: AbstractVertxBasedCoapAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the adapter fails the upload of an event with a 4.03 result if the device belongs to a tenant for
 * which the adapter is disabled.
 */
@Test
public void testUploadTelemetryFailsForDisabledTenant() {

    // GIVEN an adapter
    final DownstreamSender sender = givenATelemetrySender(Promise.promise());
    // which is disabled for tenant "my-tenant"
    final TenantObject myTenantConfig = TenantObject.from("my-tenant", true);
    myTenantConfig.addAdapter(new Adapter(ADAPTER_TYPE).setEnabled(Boolean.FALSE));
    when(tenantClient.get(eq("my-tenant"), any(SpanContext.class))).thenReturn(Future.succeededFuture(myTenantConfig));
    final CoapServer server = getCoapServer(false);
    final AbstractVertxBasedCoapAdapter<CoapAdapterProperties> adapter = getAdapter(server, true, null);

    // WHEN a device that belongs to "my-tenant" publishes a telemetry message
    final Buffer payload = Buffer.buffer("some payload");
    final CoapExchange coapExchange = newCoapExchange(payload, Type.NON, MediaTypeRegistry.TEXT_PLAIN);
    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 with code 4.03
    verify(coapExchange).respond(argThat((Response res) -> ResponseCode.FORBIDDEN.equals(res.getCode())));

    // and the message has not been forwarded downstream
    verify(sender, never()).send(any(Message.class), any(SpanContext.class));
    verify(metrics).reportTelemetry(
            eq(MetricsTags.EndpointType.TELEMETRY),
            eq("my-tenant"),
            any(),
            eq(MetricsTags.ProcessingOutcome.UNPROCESSABLE),
            eq(MetricsTags.QoS.AT_MOST_ONCE),
            eq(payload.length()),
            eq(TtdStatus.NONE),
            any());
}
 
Example #23
Source File: AbstractVertxBasedCoapAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that a telemetry message is rejected due to the limit exceeded.
 *
 */
@Test
public void testMessageLimitExceededForATelemetryMessage() {

    // GIVEN an adapter with a downstream telemetry consumer attached
    final Promise<ProtonDelivery> outcome = Promise.promise();
    final DownstreamSender sender = givenATelemetrySender(outcome);

    final CoapServer server = getCoapServer(false);
    final AbstractVertxBasedCoapAdapter<CoapAdapterProperties> adapter = getAdapter(server, true, null);

    // WHEN a device that belongs to a tenant for which the message limit is exceeded
    // publishes a telemetry message
    when(resourceLimitChecks.isMessageLimitReached(any(TenantObject.class), anyLong(), any(SpanContext.class)))
        .thenReturn(Future.succeededFuture(Boolean.TRUE));
    final Buffer payload = Buffer.buffer("some payload");
    final CoapExchange coapExchange = newCoapExchange(payload, Type.NON, MediaTypeRegistry.TEXT_PLAIN);
    final Device authenticatedDevice = new Device("tenant", "device");
    final CoapContext ctx = CoapContext.fromRequest(coapExchange);
    adapter.uploadTelemetryMessage(ctx, authenticatedDevice, authenticatedDevice);

    // THEN the message is not being forwarded downstream
    verify(sender, never()).send(any(Message.class), any(SpanContext.class));
    // and the device gets a 4.29
    verify(coapExchange).respond(argThat((Response res) -> ResponseCode.TOO_MANY_REQUESTS.equals(res.getCode())));
    verify(metrics).reportTelemetry(
            eq(MetricsTags.EndpointType.TELEMETRY),
            eq("tenant"),
            any(),
            eq(MetricsTags.ProcessingOutcome.UNPROCESSABLE),
            eq(MetricsTags.QoS.AT_MOST_ONCE),
            eq(payload.length()),
            eq(TtdStatus.NONE),
            any());
}
 
Example #24
Source File: HCoapServer.java    From SI with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void receiveRequest(CoapExchange exchange) {
	if(listener != null) {
		listener.receiveCoapRequest(exchange);
	} else {
		exchange.respond(ResponseCode.INTERNAL_SERVER_ERROR, "Not found listener");
	}
}
 
Example #25
Source File: CoapResource.java    From SI with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Delete this resource from its parents and notify all observing CoAP
 * clients that this resource is no longer accessible.
 */
public synchronized void delete() {
	Resource parent = getParent();
	if (parent != null) {
		parent.delete(this);
	}
	
	if (isObservable()) {
		clearAndNotifyObserveRelations(ResponseCode.NOT_FOUND);
	}
}
 
Example #26
Source File: CoapTransportResource.java    From iotplatform with Apache License 2.0 5 votes vote down vote up
@Override
public void handleGET(CoapExchange exchange) {
  Optional<FeatureType> featureType = getFeatureType(exchange.advanced().getRequest());
  if (!featureType.isPresent()) {
    log.trace("Missing feature type parameter");
    exchange.respond(ResponseCode.BAD_REQUEST);
  } else if (featureType.get() == FeatureType.TELEMETRY) {
    log.trace("Can't fetch/subscribe to timeseries updates");
    exchange.respond(ResponseCode.BAD_REQUEST);
  } else if (exchange.getRequestOptions().hasObserve()) {
    boolean unsubscribe = exchange.getRequestOptions().getObserve() == 1;
    MsgType msgType;
    if (featureType.get() == FeatureType.RPC) {
      msgType = unsubscribe ? MsgType.UNSUBSCRIBE_RPC_COMMANDS_REQUEST : MsgType.SUBSCRIBE_RPC_COMMANDS_REQUEST;
    } else {
      msgType = unsubscribe ? MsgType.UNSUBSCRIBE_ATTRIBUTES_REQUEST : MsgType.SUBSCRIBE_ATTRIBUTES_REQUEST;
    }
    Optional<SessionId> sessionId = processRequest(exchange, msgType);
    if (sessionId.isPresent()) {
      if (exchange.getRequestOptions().getObserve() == 1) {
        exchange.respond(ResponseCode.VALID);
      }
    }
  } else if (featureType.get() == FeatureType.ATTRIBUTES) {
    processRequest(exchange, MsgType.GET_ATTRIBUTES_REQUEST);
  } else {
    log.trace("Invalid feature type parameter");
    exchange.respond(ResponseCode.BAD_REQUEST);
  }
}
 
Example #27
Source File: HCoapServer.java    From SI with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void receiveRequest(CoapExchange exchange) {
	if(listener != null) {
		listener.receiveCoapRequest(exchange);
	} else {
		exchange.respond(ResponseCode.INTERNAL_SERVER_ERROR, "Not found listener");
	}
}
 
Example #28
Source File: AbstractVertxBasedCoapAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that an event message is rejected due to the limit exceeded.
 *
 */
@Test
public void testMessageLimitExceededForAnEventMessage() {

    // GIVEN an adapter with a downstream event consumer attached
    final Promise<ProtonDelivery> outcome = Promise.promise();
    final DownstreamSender sender = givenAnEventSender(outcome);

    final CoapServer server = getCoapServer(false);
    final AbstractVertxBasedCoapAdapter<CoapAdapterProperties> adapter = getAdapter(server, true, null);

    // WHEN the message limit exceeds
    when(resourceLimitChecks.isMessageLimitReached(any(TenantObject.class), anyLong(), any(SpanContext.class)))
            .thenReturn(Future.succeededFuture(Boolean.TRUE));

    // WHEN a device publishes an event message
    final Buffer payload = Buffer.buffer("some payload");
    final CoapExchange coapExchange = newCoapExchange(payload, Type.CON, MediaTypeRegistry.TEXT_PLAIN);
    final Device authenticatedDevice = new Device("tenant", "device");
    final CoapContext ctx = CoapContext.fromRequest(coapExchange);
    adapter.uploadEventMessage(ctx, authenticatedDevice, authenticatedDevice);

    // THEN the message is not being forwarded downstream
    verify(sender, never()).sendAndWaitForOutcome(any(Message.class), any(SpanContext.class));
    // and the device gets a 4.29
    final ArgumentCaptor<Response> captor = ArgumentCaptor.forClass(Response.class);
    verify(coapExchange).respond(captor.capture());
    assertThat(captor.getValue().getCode()).isEqualTo(ResponseCode.TOO_MANY_REQUESTS);
    verify(metrics).reportTelemetry(
            eq(MetricsTags.EndpointType.EVENT),
            eq("tenant"),
            any(),
            eq(MetricsTags.ProcessingOutcome.UNPROCESSABLE),
            eq(MetricsTags.QoS.AT_LEAST_ONCE),
            eq(payload.length()),
            eq(TtdStatus.NONE),
            any());
}
 
Example #29
Source File: InCse.java    From SI with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private boolean sendCoapResponse(OneM2mResponse resMessage, CoapExchange exchange) {
	
	if (exchange == null) {
		return false;
	}
	
	coapMap.remove(resMessage.getRequestIdentifier());
	
	try {
		Response response = CoapResponseCodec.encode(resMessage, exchange);
		
		log.debug("<< SEND CoAP MESSAGE:");
		log.debug(response.toString());
		log.debug(response.getPayloadString());
		exchange.respond(response);
		// added in 2017-10-31 to support CSE-relative Unstructured addressing 
		//System.out.println("############### uripath-size=" + exchange.getRequestOptions().getUriPath().size());
		//System.out.println("############### resMessage.getResponseStatusCode()=" + resMessage.getResponseStatusCode());
		///System.out.println("############### resourceId=" + ((Resource)resMessage.getContentObject()).getResourceID());
		
		int len = exchange.getRequestOptions().getUriPath().size();
		int resCode = resMessage.getResponseStatusCode();
		
		if(resCode == 2001 && len == 1) {
			String resourceId = ((Resource)resMessage.getContentObject()).getResourceID();
			coapServer.add(coapServer.new HCoapResource(resourceId));
		}
		//coapServer.add(resources)
		
		return true;
	} catch (Exception e) {
		
		e.printStackTrace();
		
		exchange.respond(ResponseCode.INTERNAL_SERVER_ERROR, "Respose encoding failed");
	}
	
	return false;
}
 
Example #30
Source File: InCse.java    From SI with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private boolean sendCoapResponse(OneM2mResponse resMessage, CoapExchange exchange) {
	
	if (exchange == null) {
		return false;
	}
	
	coapMap.remove(resMessage.getRequestIdentifier());
	
	try {
		Response response = CoapResponseCodec.encode(resMessage, exchange);
		
		log.debug("<< SEND CoAP MESSAGE:");
		log.debug(response.toString());
		log.debug(response.getPayloadString());
		exchange.respond(response);
		// added in 2017-10-31 to support CSE-relative Unstructured addressing 
		//System.out.println("############### uripath-size=" + exchange.getRequestOptions().getUriPath().size());
		//System.out.println("############### resMessage.getResponseStatusCode()=" + resMessage.getResponseStatusCode());
		///System.out.println("############### resourceId=" + ((Resource)resMessage.getContentObject()).getResourceID());
		
		int len = exchange.getRequestOptions().getUriPath().size();
		int resCode = resMessage.getResponseStatusCode();
		
		if(resCode == 2001 && len == 1) {
			String resourceId = ((Resource)resMessage.getContentObject()).getResourceID();
			coapServer.add(coapServer.new HCoapResource(resourceId));
		}
		//coapServer.add(resources)
		
		return true;
	} catch (Exception e) {
		
		e.printStackTrace();
		
		exchange.respond(ResponseCode.INTERNAL_SERVER_ERROR, "Respose encoding failed");
	}
	
	return false;
}