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);
});
}
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());
}
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();
}
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();
}
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();
}
Aggregations