Search in sources :

Example 1 with LoraProvider

use of org.eclipse.hono.adapter.lora.providers.LoraProvider in project hono by eclipse.

the class LoraProtocolAdapter method handleCommand.

private void handleCommand(final CommandContext commandContext) {
    Tags.COMPONENT.set(commandContext.getTracingSpan(), getTypeName());
    final Sample timer = metrics.startTimer();
    final Command command = commandContext.getCommand();
    if (command.getGatewayId() == null) {
        final String errorMsg = "no gateway defined for command";
        LOG.debug("{} [{}]", errorMsg, command);
        commandContext.release(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, errorMsg));
        return;
    }
    final String tenant = command.getTenant();
    final String gatewayId = command.getGatewayId();
    final LoraProvider loraProvider = Optional.ofNullable(commandSubscriptions.get(new SubscriptionKey(tenant, gatewayId))).map(Pair::two).orElse(null);
    if (loraProvider == null) {
        LOG.debug("received command for unknown gateway [{}] for tenant [{}]", gatewayId, tenant);
        TracingHelper.logError(commandContext.getTracingSpan(), String.format("received command for unknown gateway [%s]", gatewayId));
        commandContext.release(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "received command for unknown gateway"));
        return;
    }
    final Future<TenantObject> tenantTracker = getTenantConfiguration(tenant, commandContext.getTracingContext());
    tenantTracker.compose(tenantObject -> {
        if (command.isValid()) {
            return checkMessageLimit(tenantObject, command.getPayloadSize(), commandContext.getTracingContext());
        } else {
            return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "malformed command message"));
        }
    }).compose(success -> getRegistrationClient().assertRegistration(tenant, gatewayId, null, commandContext.getTracingContext())).compose(registrationAssertion -> sendCommandToGateway(commandContext, loraProvider, registrationAssertion.getCommandEndpoint())).onSuccess(aVoid -> {
        addMicrometerSample(commandContext, timer);
        commandContext.accept();
        metrics.reportCommand(command.isOneWay() ? Direction.ONE_WAY : Direction.REQUEST, tenant, tenantTracker.result(), MetricsTags.ProcessingOutcome.FORWARDED, command.getPayloadSize(), timer);
    }).onFailure(t -> {
        LOG.debug("error sending command", t);
        commandContext.release(t);
        metrics.reportCommand(command.isOneWay() ? Direction.ONE_WAY : Direction.REQUEST, tenant, tenantTracker.result(), MetricsTags.ProcessingOutcome.from(t), command.getPayloadSize(), timer);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) LoraProviderMalformedPayloadException(org.eclipse.hono.adapter.lora.providers.LoraProviderMalformedPayloadException) LoggerFactory(org.slf4j.LoggerFactory) Router(io.vertx.ext.web.Router) Tag(io.opentracing.tag.Tag) RoutingContext(io.vertx.ext.web.RoutingContext) Tags(io.opentracing.tag.Tags) Map(java.util.Map) Pair(org.eclipse.hono.util.Pair) Fields(io.opentracing.log.Fields) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) TenantServiceBasedX509Authentication(org.eclipse.hono.adapter.auth.device.TenantServiceBasedX509Authentication) ChainAuthHandler(io.vertx.ext.web.handler.ChainAuthHandler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CommandContext(org.eclipse.hono.client.command.CommandContext) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) Message(io.vertx.core.eventbus.Message) EventConstants(org.eclipse.hono.util.EventConstants) StringTag(io.opentracing.tag.StringTag) Future(io.vertx.core.Future) HonoBasicAuthHandler(org.eclipse.hono.adapter.http.HonoBasicAuthHandler) Device(org.eclipse.hono.auth.Device) Objects(java.util.Objects) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) X509AuthHandler(org.eclipse.hono.adapter.http.X509AuthHandler) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Optional(java.util.Optional) Span(io.opentracing.Span) UsernamePasswordCredentials(org.eclipse.hono.adapter.auth.device.UsernamePasswordCredentials) CommandEndpoint(org.eclipse.hono.util.CommandEndpoint) HttpContext(org.eclipse.hono.service.http.HttpContext) Json(io.vertx.core.json.Json) LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) WebClient(io.vertx.ext.web.client.WebClient) Command(org.eclipse.hono.client.command.Command) ClientErrorException(org.eclipse.hono.client.ClientErrorException) TenantDisabledOrNotRegisteredException(org.eclipse.hono.client.registry.TenantDisabledOrNotRegisteredException) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) TracingHandler(org.eclipse.hono.service.http.TracingHandler) CompositeFuture(io.vertx.core.CompositeFuture) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) HttpUtils(org.eclipse.hono.service.http.HttpUtils) LinkedList(java.util.LinkedList) UsernamePasswordAuthProvider(org.eclipse.hono.adapter.auth.device.UsernamePasswordAuthProvider) Logger(org.slf4j.Logger) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) AbstractVertxBasedHttpProtocolAdapter(org.eclipse.hono.adapter.http.AbstractVertxBasedHttpProtocolAdapter) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Sample(io.micrometer.core.instrument.Timer.Sample) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) HttpRequest(io.vertx.ext.web.client.HttpRequest) DeviceCredentialsAuthProvider(org.eclipse.hono.adapter.auth.device.DeviceCredentialsAuthProvider) X509AuthProvider(org.eclipse.hono.adapter.auth.device.X509AuthProvider) HttpMethod(io.vertx.core.http.HttpMethod) HttpProtocolAdapterProperties(org.eclipse.hono.adapter.http.HttpProtocolAdapterProperties) SubjectDnCredentials(org.eclipse.hono.adapter.auth.device.SubjectDnCredentials) TenantObject(org.eclipse.hono.util.TenantObject) LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) Command(org.eclipse.hono.client.command.Command) Sample(io.micrometer.core.instrument.Timer.Sample) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServerErrorException(org.eclipse.hono.client.ServerErrorException)

Example 2 with LoraProvider

use of org.eclipse.hono.adapter.lora.providers.LoraProvider in project hono by eclipse.

the class LoraProtocolAdapter method registerCommandConsumerIfNeeded.

private void registerCommandConsumerIfNeeded(final LoraProvider provider, final Device gatewayDevice, final SpanContext context) {
    final String tenantId = gatewayDevice.getTenantId();
    final String gatewayId = gatewayDevice.getDeviceId();
    final SubscriptionKey key = new SubscriptionKey(tenantId, gatewayId);
    if (commandSubscriptions.containsKey(key)) {
        return;
    }
    // use FOLLOWS_FROM span since this operation is decoupled from the rest of the request handling
    final Span currentSpan = TracingHelper.buildFollowsFromSpan(tracer, context, "create command consumer").withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).start();
    TracingHelper.setDeviceTags(currentSpan, tenantId, gatewayId);
    TAG_LORA_PROVIDER.set(currentSpan, provider.getProviderName());
    getRegistrationClient().assertRegistration(tenantId, gatewayId, null, currentSpan.context()).onFailure(thr -> {
        LOG.debug("error asserting gateway registration, no command consumer will be created [tenant: {}, gateway-id: {}]", tenantId, gatewayId);
        TracingHelper.logError(currentSpan, "error asserting gateway registration, no command consumer will be created", thr);
    }).compose(assertion -> {
        if (assertion.getCommandEndpoint() == null) {
            LOG.debug("gateway has no command endpoint defined, skipping command consumer creation [tenant: {}, gateway-id: {}]", tenantId, gatewayId);
            currentSpan.log("gateway has no command endpoint defined, skipping command consumer creation");
            return Future.succeededFuture((Void) null);
        }
        return getCommandConsumerFactory().createCommandConsumer(tenantId, gatewayId, this::handleCommand, null, currentSpan.context()).onFailure(thr -> TracingHelper.logError(currentSpan, thr)).map(commandConsumer -> commandSubscriptions.put(key, Pair.of(commandConsumer, provider))).mapEmpty();
    }).onComplete(ar -> currentSpan.finish());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) LoraProviderMalformedPayloadException(org.eclipse.hono.adapter.lora.providers.LoraProviderMalformedPayloadException) LoggerFactory(org.slf4j.LoggerFactory) Router(io.vertx.ext.web.Router) Tag(io.opentracing.tag.Tag) RoutingContext(io.vertx.ext.web.RoutingContext) Tags(io.opentracing.tag.Tags) Map(java.util.Map) Pair(org.eclipse.hono.util.Pair) Fields(io.opentracing.log.Fields) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) TenantServiceBasedX509Authentication(org.eclipse.hono.adapter.auth.device.TenantServiceBasedX509Authentication) ChainAuthHandler(io.vertx.ext.web.handler.ChainAuthHandler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CommandContext(org.eclipse.hono.client.command.CommandContext) MetricsTags(org.eclipse.hono.service.metric.MetricsTags) Message(io.vertx.core.eventbus.Message) EventConstants(org.eclipse.hono.util.EventConstants) StringTag(io.opentracing.tag.StringTag) Future(io.vertx.core.Future) HonoBasicAuthHandler(org.eclipse.hono.adapter.http.HonoBasicAuthHandler) Device(org.eclipse.hono.auth.Device) Objects(java.util.Objects) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) X509AuthHandler(org.eclipse.hono.adapter.http.X509AuthHandler) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Optional(java.util.Optional) Span(io.opentracing.Span) UsernamePasswordCredentials(org.eclipse.hono.adapter.auth.device.UsernamePasswordCredentials) CommandEndpoint(org.eclipse.hono.util.CommandEndpoint) HttpContext(org.eclipse.hono.service.http.HttpContext) Json(io.vertx.core.json.Json) LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) WebClient(io.vertx.ext.web.client.WebClient) Command(org.eclipse.hono.client.command.Command) ClientErrorException(org.eclipse.hono.client.ClientErrorException) TenantDisabledOrNotRegisteredException(org.eclipse.hono.client.registry.TenantDisabledOrNotRegisteredException) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) TracingHandler(org.eclipse.hono.service.http.TracingHandler) CompositeFuture(io.vertx.core.CompositeFuture) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) HttpUtils(org.eclipse.hono.service.http.HttpUtils) LinkedList(java.util.LinkedList) UsernamePasswordAuthProvider(org.eclipse.hono.adapter.auth.device.UsernamePasswordAuthProvider) Logger(org.slf4j.Logger) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) AbstractVertxBasedHttpProtocolAdapter(org.eclipse.hono.adapter.http.AbstractVertxBasedHttpProtocolAdapter) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Sample(io.micrometer.core.instrument.Timer.Sample) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) HttpRequest(io.vertx.ext.web.client.HttpRequest) DeviceCredentialsAuthProvider(org.eclipse.hono.adapter.auth.device.DeviceCredentialsAuthProvider) X509AuthProvider(org.eclipse.hono.adapter.auth.device.X509AuthProvider) HttpMethod(io.vertx.core.http.HttpMethod) HttpProtocolAdapterProperties(org.eclipse.hono.adapter.http.HttpProtocolAdapterProperties) SubjectDnCredentials(org.eclipse.hono.adapter.auth.device.SubjectDnCredentials) Span(io.opentracing.Span)

Example 3 with LoraProvider

use of org.eclipse.hono.adapter.lora.providers.LoraProvider in project hono by eclipse.

the class LoraProtocolAdapterTest method handleProviderRouteDiscardsJoinMessages.

/**
 * Verifies that the provider route discards join messages.
 */
@Test
public void handleProviderRouteDiscardsJoinMessages() {
    givenATelemetrySenderForAnyTenant();
    final LoraMessage message = mock(LoraMessage.class);
    when(message.getType()).thenReturn(LoraMessageType.JOIN);
    final LoraProvider providerMock = getLoraProviderMock(message);
    final HttpContext httpContext = newHttpContext();
    adapter.handleProviderRoute(httpContext, providerMock);
    verify(httpContext.getRoutingContext()).put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, TEST_PROVIDER);
    assertNoTelemetryMessageHasBeenSentDownstream();
    verify(httpContext.getRoutingContext().response()).setStatusCode(HttpResponseStatus.ACCEPTED.code());
    verify(processMessageSpan).finish();
}
Also used : LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Example 4 with LoraProvider

use of org.eclipse.hono.adapter.lora.providers.LoraProvider in project hono by eclipse.

the class LoraProtocolAdapterTest method handleProviderRouteCausesBadRequestForFailureToParseBody.

/**
 * Verifies that the provider route rejects a request if the request body cannot
 * be parsed.
 */
@Test
public void handleProviderRouteCausesBadRequestForFailureToParseBody() {
    givenATelemetrySenderForAnyTenant();
    final LoraProvider providerMock = getLoraProviderMock();
    when(providerMock.getMessage(any(RoutingContext.class))).thenThrow(new LoraProviderMalformedPayloadException("no device ID"));
    final HttpContext httpContext = newHttpContext();
    adapter.handleProviderRoute(httpContext, providerMock);
    verify(httpContext.getRoutingContext()).put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, TEST_PROVIDER);
    assertNoTelemetryMessageHasBeenSentDownstream();
    verifyBadRequest(httpContext.getRoutingContext());
    verify(processMessageSpan).finish();
}
Also used : RoutingContext(io.vertx.ext.web.RoutingContext) LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) HttpContext(org.eclipse.hono.service.http.HttpContext) LoraProviderMalformedPayloadException(org.eclipse.hono.adapter.lora.providers.LoraProviderMalformedPayloadException) Test(org.junit.jupiter.api.Test)

Example 5 with LoraProvider

use of org.eclipse.hono.adapter.lora.providers.LoraProvider in project hono by eclipse.

the class LoraProtocolAdapterTest method handleProviderRouteDiscardsDownlinkMessages.

/**
 * Verifies that the provider route discards downlink messages.
 */
@Test
public void handleProviderRouteDiscardsDownlinkMessages() {
    givenATelemetrySenderForAnyTenant();
    final LoraMessage message = mock(LoraMessage.class);
    when(message.getType()).thenReturn(LoraMessageType.DOWNLINK);
    final LoraProvider providerMock = getLoraProviderMock(message);
    final HttpContext httpContext = newHttpContext();
    adapter.handleProviderRoute(httpContext, providerMock);
    verify(httpContext.getRoutingContext()).put(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER, TEST_PROVIDER);
    assertNoTelemetryMessageHasBeenSentDownstream();
    verify(httpContext.response()).setStatusCode(HttpResponseStatus.ACCEPTED.code());
    verify(processMessageSpan).finish();
}
Also used : LoraProvider(org.eclipse.hono.adapter.lora.providers.LoraProvider) HttpContext(org.eclipse.hono.service.http.HttpContext) Test(org.junit.jupiter.api.Test)

Aggregations

LoraProvider (org.eclipse.hono.adapter.lora.providers.LoraProvider)13 HttpContext (org.eclipse.hono.service.http.HttpContext)10 Test (org.junit.jupiter.api.Test)8 RoutingContext (io.vertx.ext.web.RoutingContext)5 CommandConsumer (org.eclipse.hono.client.command.CommandConsumer)5 CommandEndpoint (org.eclipse.hono.util.CommandEndpoint)5 Buffer (io.vertx.core.buffer.Buffer)4 JsonObject (io.vertx.core.json.JsonObject)4 LoraProviderMalformedPayloadException (org.eclipse.hono.adapter.lora.providers.LoraProviderMalformedPayloadException)4 Command (org.eclipse.hono.client.command.Command)4 CommandContext (org.eclipse.hono.client.command.CommandContext)4 TracingHandler (org.eclipse.hono.service.http.TracingHandler)4 Sample (io.micrometer.core.instrument.Timer.Sample)3 Span (io.opentracing.Span)3 SpanContext (io.opentracing.SpanContext)3 Future (io.vertx.core.Future)3 HttpRequest (io.vertx.ext.web.client.HttpRequest)3 WebClient (io.vertx.ext.web.client.WebClient)3 HttpURLConnection (java.net.HttpURLConnection)3 ArrayList (java.util.ArrayList)3