Skip to content

Commit 39e59a0

Browse files
committed
[#3520] specific metrics for unknown messages
Signed-off-by: Bob Claerhout <claerhout.bob@gmail.com>
1 parent 4a8911a commit 39e59a0

43 files changed

Lines changed: 46028 additions & 39 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

adapter-base/src/main/java/org/eclipse/hono/adapter/AbstractProtocolAdapterBase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.eclipse.hono.client.telemetry.TelemetrySender;
4343
import org.eclipse.hono.client.util.ServiceClient;
4444
import org.eclipse.hono.service.AbstractServiceBase;
45+
import org.eclipse.hono.service.AdapterDisabledException;
4546
import org.eclipse.hono.service.auth.ValidityBasedTrustOptions;
4647
import org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome;
4748
import org.eclipse.hono.service.util.ServiceBaseUtils;

adapters/amqp/src/main/java/org/eclipse/hono/adapter/amqp/VertxBasedAmqpProtocolAdapter.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.apache.qpid.proton.message.Message;
4242
import org.eclipse.hono.adapter.AbstractProtocolAdapterBase;
4343
import org.eclipse.hono.adapter.AdapterConnectionsExceededException;
44-
import org.eclipse.hono.adapter.AdapterDisabledException;
4544
import org.eclipse.hono.adapter.AuthorizationException;
4645
import org.eclipse.hono.adapter.auth.device.CredentialsApiAuthProvider;
4746
import org.eclipse.hono.adapter.auth.device.DeviceCredentials;
@@ -67,8 +66,10 @@
6766
import org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification;
6867
import org.eclipse.hono.notification.deviceregistry.LifecycleChange;
6968
import org.eclipse.hono.notification.deviceregistry.TenantChangeNotification;
69+
import org.eclipse.hono.service.AdapterDisabledException;
7070
import org.eclipse.hono.service.auth.DeviceUser;
7171
import org.eclipse.hono.service.http.HttpUtils;
72+
import org.eclipse.hono.service.metric.MetricsTags;
7273
import org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome;
7374
import org.eclipse.hono.service.metric.MetricsTags.Direction;
7475
import org.eclipse.hono.service.metric.MetricsTags.EndpointType;
@@ -1325,7 +1326,8 @@ private Future<Void> doUploadMessage(
13251326
ProcessingOutcome.from(t),
13261327
context.isRemotelySettled() ? QoS.AT_MOST_ONCE : QoS.AT_LEAST_ONCE,
13271328
context.getPayloadSize(),
1328-
context.getTimer());
1329+
context.getTimer(),
1330+
MetricsTags.Reason.from(t));
13291331
return Future.failedFuture(t);
13301332

13311333
}).map(ok -> {

adapters/amqp/src/test/java/org/eclipse/hono/adapter/amqp/VertxBasedAmqpProtocolAdapterTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ public void testUploadTelemetryMessageFailsForDisabledAdapter(final VertxTestCon
388388
eq(ProcessingOutcome.UNPROCESSABLE),
389389
eq(MetricsTags.QoS.AT_LEAST_ONCE),
390390
eq(payload.length()),
391-
any());
391+
any(),
392+
eq(MetricsTags.Reason.TENANT_DISABLED_FOR_ADAPTER));
392393
});
393394
ctx.completeNow();
394395
}));
@@ -1000,7 +1001,8 @@ public void testMessageLimitExceededForATelemetryMessage(final VertxTestContext
10001001
eq(ProcessingOutcome.UNPROCESSABLE),
10011002
eq(MetricsTags.QoS.AT_LEAST_ONCE),
10021003
eq(payload.length()),
1003-
any());
1004+
any(),
1005+
eq(MetricsTags.Reason.MESSAGE_LIMIT_EXCEEDED));
10041006
});
10051007
}
10061008

@@ -1027,7 +1029,8 @@ public void testMessageLimitExceededForAnEventMessage(final VertxTestContext ctx
10271029
eq(ProcessingOutcome.UNPROCESSABLE),
10281030
eq(MetricsTags.QoS.AT_LEAST_ONCE),
10291031
eq(payload.length()),
1030-
any());
1032+
any(),
1033+
eq(MetricsTags.Reason.MESSAGE_LIMIT_EXCEEDED));
10311034
});
10321035
}
10331036

adapters/coap/src/main/java/org/eclipse/hono/adapter/coap/AbstractHonoResource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,8 @@ protected final Future<Void> doUploadMessage(
413413
qos,
414414
payload.length(),
415415
getTtdStatus(context),
416-
context.getTimer());
416+
context.getTimer(),
417+
MetricsTags.Reason.from(t));
417418
TracingHelper.logError(currentSpan, t);
418419
commandConsumerClosedTracker.onComplete(res -> currentSpan.finish());
419420
return Future.failedFuture(t);

adapters/coap/src/test/java/org/eclipse/hono/adapter/coap/EventResourceTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ public void testUploadEventFailsForRejectedOutcome(final VertxTestContext ctx) {
142142
eq(MetricsTags.QoS.AT_LEAST_ONCE),
143143
eq(payload.length()),
144144
eq(TtdStatus.NONE),
145-
any());
145+
any(),
146+
eq(MetricsTags.Reason.UNKNOWN));
146147
});
147148
ctx.completeNow();
148149
}));
@@ -187,7 +188,8 @@ public void testMessageLimitExceededForAnEventMessage(final VertxTestContext ctx
187188
eq(MetricsTags.QoS.AT_LEAST_ONCE),
188189
eq(payload.length()),
189190
eq(TtdStatus.NONE),
190-
any());
191+
any(),
192+
eq(MetricsTags.Reason.MESSAGE_LIMIT_EXCEEDED));
191193
});
192194
ctx.completeNow();
193195
}));

adapters/coap/src/test/java/org/eclipse/hono/adapter/coap/TelemetryResourceTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.eclipse.hono.client.ClientErrorException;
4040
import org.eclipse.hono.client.ServerErrorException;
4141
import org.eclipse.hono.client.command.CommandContext;
42+
import org.eclipse.hono.service.AdapterDisabledException;
4243
import org.eclipse.hono.service.auth.DeviceUser;
4344
import org.eclipse.hono.service.metric.MetricsTags;
4445
import org.eclipse.hono.service.metric.MetricsTags.Direction;
@@ -92,7 +93,7 @@ public void testUploadTelemetryFailsForDisabledTenant(final VertxTestContext ctx
9293
final var resource = givenAResource(adapter);
9394
// which is disabled for tenant "my-tenant"
9495
when(adapter.isAdapterEnabled(any(TenantObject.class)))
95-
.thenReturn(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN)));
96+
.thenReturn(Future.failedFuture(new AdapterDisabledException("my-tenant")));
9697

9798
// WHEN a device that belongs to "my-tenant" publishes a telemetry message
9899
final Buffer payload = Buffer.buffer("some payload");
@@ -118,7 +119,8 @@ public void testUploadTelemetryFailsForDisabledTenant(final VertxTestContext ctx
118119
eq(MetricsTags.QoS.AT_MOST_ONCE),
119120
eq(payload.length()),
120121
eq(TtdStatus.NONE),
121-
any());
122+
any(),
123+
eq(MetricsTags.Reason.TENANT_DISABLED_FOR_ADAPTER));
122124
});
123125
ctx.completeNow();
124126
}));
@@ -371,7 +373,8 @@ public void testMessageLimitExceededForATelemetryMessage(final VertxTestContext
371373
eq(MetricsTags.QoS.AT_MOST_ONCE),
372374
eq(payload.length()),
373375
eq(TtdStatus.NONE),
374-
any());
376+
any(),
377+
eq(MetricsTags.Reason.MESSAGE_LIMIT_EXCEEDED));
375378
});
376379
ctx.completeNow();
377380
}));
@@ -560,7 +563,8 @@ public void testUploadTelemetryReleasesCommandForFailedDownstreamSender(final Ve
560563
eq(MetricsTags.QoS.AT_LEAST_ONCE),
561564
eq(payload.length()),
562565
eq(TtdStatus.COMMAND),
563-
any());
566+
any(),
567+
eq(MetricsTags.Reason.UNKNOWN));
564568
// and the command delivery is released
565569
verify(commandContext).release(any(Throwable.class));
566570
});

adapters/http-base/src/main/java/org/eclipse/hono/adapter/http/AbstractVertxBasedHttpProtocolAdapter.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.eclipse.hono.util.CommandConstants;
4646
import org.eclipse.hono.util.Constants;
4747
import org.eclipse.hono.util.MessageHelper;
48+
import org.eclipse.hono.util.QoS;
4849
import org.eclipse.hono.util.RegistrationAssertion;
4950
import org.eclipse.hono.util.Strings;
5051
import org.eclipse.hono.util.TenantObject;
@@ -85,7 +86,7 @@ public abstract class AbstractVertxBasedHttpProtocolAdapter<T extends HttpProtoc
8586

8687
private static final String KEY_MATCH_ALL_ROUTE_APPLIED = "matchAllRouteApplied";
8788

88-
private HttpAdapterMetrics metrics = HttpAdapterMetrics.NOOP;
89+
protected HttpAdapterMetrics metrics = HttpAdapterMetrics.NOOP;
8990
private HttpServer server;
9091
private HttpServer insecureServer;
9192

@@ -203,7 +204,15 @@ public final void doStart(final Promise<Void> startPromise) {
203204
.onComplete(startPromise);
204205
}
205206

206-
private Sample getMicrometerSample(final RoutingContext ctx) {
207+
/**
208+
* Gets the timer used to track the processing of a telemetry message.
209+
*
210+
* @param ctx The routing context to extract the sample from.
211+
* @return The sample or {@code null} if the context does not
212+
* contain a sample.
213+
* @throws NullPointerException if ctx is {@code null}.
214+
*/
215+
protected Sample getMicrometerSample(final RoutingContext ctx) {
207216
return ctx.get(KEY_MICROMETER_SAMPLE);
208217
}
209218

@@ -778,7 +787,8 @@ private void doUploadMessage(
778787
qos,
779788
payloadSize,
780789
ctx.getTtdStatus(),
781-
getMicrometerSample(ctx.getRoutingContext()));
790+
getMicrometerSample(ctx.getRoutingContext()),
791+
MetricsTags.Reason.from(t));
782792
TracingHelper.logError(currentSpan, t);
783793
currentSpan.finish();
784794
return Future.failedFuture(t);
@@ -1295,9 +1305,16 @@ public final void uploadCommandResponseMessage(
12951305
});
12961306
}
12971307

1298-
private static MetricsTags.QoS getQoSLevel(
1299-
final EndpointType endpoint,
1300-
final org.eclipse.hono.util.QoS requestedQos) {
1308+
/**
1309+
* Get the QoS based on the endpoint and the requested QoS.
1310+
*
1311+
* @param endpoint The endpoint the message was sent to.
1312+
* @param requestedQos The QoS requested by the sender.
1313+
* @return The resulting QoS.
1314+
*/
1315+
protected static MetricsTags.QoS getQoSLevel(
1316+
final EndpointType endpoint,
1317+
final QoS requestedQos) {
13011318

13021319
if (endpoint == EndpointType.EVENT) {
13031320
return MetricsTags.QoS.AT_LEAST_ONCE;

adapters/http-base/src/test/java/org/eclipse/hono/adapter/http/AbstractVertxBasedHttpProtocolAdapterTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,8 @@ public void testUploadTelemetryWithTtdClosesCommandConsumerIfSendingFails() {
703703
eq(MetricsTags.QoS.AT_MOST_ONCE),
704704
eq(payload.length()),
705705
eq(TtdStatus.NONE),
706-
any());
706+
any(),
707+
eq(MetricsTags.Reason.UNKNOWN));
707708
// and the command consumer is closed
708709
verify(commandConsumer).close(eq(false), any());
709710
}
@@ -786,7 +787,8 @@ public void testMessageLimitExceededForATelemetryMessage() {
786787
eq(MetricsTags.QoS.AT_MOST_ONCE),
787788
eq(payload.length()),
788789
eq(TtdStatus.NONE),
789-
any());
790+
any(),
791+
eq(MetricsTags.Reason.MESSAGE_LIMIT_EXCEEDED));
790792
}
791793

792794
/**
@@ -825,7 +827,8 @@ public void testMessageLimitExceededForAnEventMessage() {
825827
eq(MetricsTags.QoS.AT_LEAST_ONCE),
826828
eq(payload.length()),
827829
eq(TtdStatus.NONE),
828-
any());
830+
any(),
831+
eq(MetricsTags.Reason.MESSAGE_LIMIT_EXCEEDED));
829832
}
830833

831834
/**

adapters/lora/src/main/java/org/eclipse/hono/adapter/lora/LoraProtocolAdapter.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ void handleProviderRoute(final HttpContext ctx, final LoraProvider provider) {
236236

237237
final var gatewayDevice = ctx.getAuthenticatedDevice();
238238
TracingHelper.setDeviceTags(currentSpan, gatewayDevice.getTenantId(), gatewayDevice.getDeviceId());
239+
240+
final Future<TenantObject> tenantTracker = getTenantConfiguration(gatewayDevice.getTenantId(), currentSpan.context());
241+
final MetricsTags.EndpointType endpoint = MetricsTags.EndpointType.fromString(ctx.getRequestedResource().getEndpoint());
242+
final MetricsTags.QoS qos = getQoSLevel(endpoint, ctx.getRequestedQos());
243+
239244
try {
240245
final LoraMessage loraMessage = provider.getMessage(ctx.getRoutingContext());
241246
final LoraMessageType type = loraMessage.getType();
@@ -263,18 +268,41 @@ void handleProviderRoute(final HttpContext ctx, final LoraProvider provider) {
263268
registerCommandConsumerIfNeeded(provider, gatewayDevice, currentSpan.context());
264269
break;
265270
default:
271+
266272
LOG.debug("discarding message of unsupported type [tenant: {}, device-id: {}, type: {}]",
267-
gatewayDevice.getTenantId(), deviceId, type);
273+
gatewayDevice.getTenantId(), deviceId, type);
268274
currentSpan.log("discarding message of unsupported type");
269275
currentSpan.finish();
270276
// discard the message but return 202 to not cause errors on the LoRa provider side
271277
handle202(ctx.getRoutingContext());
278+
279+
final MetricsTags.Reason reason = type == LoraMessageType.UNKNOWN ? MetricsTags.Reason.UNKNOWN_TYPE : MetricsTags.Reason.UNSUPPORTED_TYPE;
280+
metrics.reportTelemetry(
281+
endpoint,
282+
gatewayDevice.getTenantId(),
283+
tenantTracker.result(),
284+
MetricsTags.ProcessingOutcome.UNPROCESSABLE,
285+
qos,
286+
ctx.getRoutingContext().body().buffer().length(),
287+
ctx.getTtdStatus(),
288+
getMicrometerSample(ctx.getRoutingContext()),
289+
reason);
272290
}
273291
} catch (final LoraProviderMalformedPayloadException e) {
274292
LOG.debug("error processing request from provider [name: {}]", provider.getProviderName(), e);
275293
TracingHelper.logError(currentSpan, "error processing request", e);
276294
currentSpan.finish();
277295
handle400(ctx.getRoutingContext(), ERROR_MSG_INVALID_PAYLOAD);
296+
metrics.reportTelemetry(
297+
endpoint,
298+
gatewayDevice.getTenantId(),
299+
tenantTracker.result(),
300+
MetricsTags.ProcessingOutcome.UNPROCESSABLE,
301+
qos,
302+
ctx.getRoutingContext().body().buffer().length(),
303+
ctx.getTtdStatus(),
304+
getMicrometerSample(ctx.getRoutingContext()),
305+
MetricsTags.Reason.BAD_SYNTAX);
278306
}
279307
}
280308

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Copyright (c) 2023 Contributors to the Eclipse Foundation
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
14+
15+
package org.eclipse.hono.adapter.lora;
16+
17+
import io.vertx.core.buffer.Buffer;
18+
19+
20+
/**
21+
* A Lora message that contains unknown data sent from an end-device to a Network Server.
22+
*
23+
*/
24+
public class UnknownLoraMessage implements LoraMessage {
25+
26+
/**
27+
* {@inheritDoc}
28+
*/
29+
@Override
30+
public final byte[] getDevEUI() {
31+
return new byte[0];
32+
}
33+
34+
/**
35+
* {@inheritDoc}
36+
*/
37+
@Override
38+
public final String getDevEUIAsString() {
39+
return "";
40+
}
41+
42+
/**
43+
* {@inheritDoc}
44+
*/
45+
@Override
46+
public final LoraMessageType getType() {
47+
return LoraMessageType.UNKNOWN;
48+
}
49+
50+
/**
51+
* {@inheritDoc}
52+
*/
53+
@Override
54+
public final Buffer getPayload() {
55+
return Buffer.buffer();
56+
}
57+
}

0 commit comments

Comments
 (0)