From 90d7318736af4ac78c32632eafd1158021edd7ed Mon Sep 17 00:00:00 2001 From: Aleksandr Kolosov Date: Tue, 3 Sep 2024 15:02:34 +0300 Subject: [PATCH] Add support for custom COAP requests logging --- .../mbed/coap/server/CoapRequestLogger.java | 89 ++++++++++++++++++ .../mbed/coap/server/CoapServerBuilder.java | 53 ++++++----- .../coap/server/messaging/CoapDispatcher.java | 16 ++-- .../mbed/coap/transport/CoapTransport.java | 35 +------- .../coap/transport/LoggingCoapTransport.java | 90 +++++++++++++++++++ .../coap/server/CoapRequestLoggerTest.java | 83 +++++++++++++++++ .../coap/server/CoapServerBuilderForTcp.java | 32 +++---- .../server/messaging/CoapTcpDispatcher.java | 24 ++--- 8 files changed, 320 insertions(+), 102 deletions(-) create mode 100644 coap-core/src/main/java/com/mbed/coap/server/CoapRequestLogger.java create mode 100644 coap-core/src/main/java/com/mbed/coap/transport/LoggingCoapTransport.java create mode 100644 coap-core/src/test/java/com/mbed/coap/server/CoapRequestLoggerTest.java diff --git a/coap-core/src/main/java/com/mbed/coap/server/CoapRequestLogger.java b/coap-core/src/main/java/com/mbed/coap/server/CoapRequestLogger.java new file mode 100644 index 00000000..0eb8a581 --- /dev/null +++ b/coap-core/src/main/java/com/mbed/coap/server/CoapRequestLogger.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022-2024 java-coap contributors (https://github.com/open-coap/java-coap) + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mbed.coap.server; + +import com.mbed.coap.packet.CoapRequest; +import com.mbed.coap.packet.CoapResponse; +import com.mbed.coap.utils.Filter; +import com.mbed.coap.utils.Service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.event.Level; +import org.slf4j.spi.LoggingEventBuilder; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; +import java.util.function.Function; + +public class CoapRequestLogger implements Filter.SimpleFilter { + private final LoggingEventBuilder loggingEventBuilder; + private final BiFunction formatter; + private final Map> mdcUpdaters; + + CoapRequestLogger(Logger logger, Level level, BiFunction formatter, Map> mdcUpdaters) { + this.loggingEventBuilder = logger.atLevel(level); + this.formatter = formatter; + this.mdcUpdaters = mdcUpdaters; + } + + @Override + public CompletableFuture apply(CoapRequest req, Service service) { + mdcUpdaters.forEach((key, updater) -> MDC.put(key, updater.apply(req))); + return service.apply(req).thenApply((resp) -> { + loggingEventBuilder.log(() -> formatter.apply(req, resp)); + mdcUpdaters.forEach((key, ___) -> MDC.remove(key)); + return resp; + }); + } + + public static CoapRequestLoggerBuilder builder() { + return new CoapRequestLoggerBuilder(); + } + + public static class CoapRequestLoggerBuilder { + private Logger logger = LoggerFactory.getLogger(CoapRequestLogger.class); + private Level level = Level.INFO; + private BiFunction formatter = (req, resp) -> req.toString() + " -> " + resp.toString(); + private final Map> mdcUpdaters = new HashMap<>(); + + public CoapRequestLoggerBuilder logger(Logger logger) { + this.logger = logger; + return this; + } + + public CoapRequestLoggerBuilder level(Level level) { + this.level = level; + return this; + } + + public CoapRequestLoggerBuilder formatter(BiFunction formatter) { + this.formatter = formatter; + return this; + } + + public CoapRequestLoggerBuilder mdc(String key, Function updater) { + mdcUpdaters.put(key, updater); + return this; + } + + public CoapRequestLogger build() { + return new CoapRequestLogger(logger, level, formatter, mdcUpdaters); + } + } +} diff --git a/coap-core/src/main/java/com/mbed/coap/server/CoapServerBuilder.java b/coap-core/src/main/java/com/mbed/coap/server/CoapServerBuilder.java index 1e0f730d..31e1cc35 100644 --- a/coap-core/src/main/java/com/mbed/coap/server/CoapServerBuilder.java +++ b/coap-core/src/main/java/com/mbed/coap/server/CoapServerBuilder.java @@ -16,43 +16,24 @@ */ package com.mbed.coap.server; -import static com.mbed.coap.transport.CoapTransport.logSent; -import static com.mbed.coap.transport.TransportContext.RESPONSE_TIMEOUT; -import static com.mbed.coap.utils.Timer.toTimer; -import static com.mbed.coap.utils.Validations.require; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toList; import com.mbed.coap.client.CoapClient; -import com.mbed.coap.packet.BlockSize; -import com.mbed.coap.packet.CoapPacket; -import com.mbed.coap.packet.CoapRequest; -import com.mbed.coap.packet.CoapResponse; -import com.mbed.coap.packet.SeparateResponse; +import com.mbed.coap.packet.*; import com.mbed.coap.server.block.BlockWiseIncomingFilter; import com.mbed.coap.server.block.BlockWiseNotificationFilter; import com.mbed.coap.server.block.BlockWiseOutgoingFilter; import com.mbed.coap.server.filter.CongestionControlFilter; import com.mbed.coap.server.filter.EchoFilter; import com.mbed.coap.server.filter.ResponseTimeoutFilter; -import com.mbed.coap.server.messaging.Capabilities; -import com.mbed.coap.server.messaging.CapabilitiesResolver; -import com.mbed.coap.server.messaging.CoapDispatcher; -import com.mbed.coap.server.messaging.CoapRequestConverter; -import com.mbed.coap.server.messaging.DuplicateDetector; -import com.mbed.coap.server.messaging.ExchangeFilter; -import com.mbed.coap.server.messaging.MessageIdSupplier; -import com.mbed.coap.server.messaging.MessageIdSupplierImpl; -import com.mbed.coap.server.messaging.ObservationMapper; -import com.mbed.coap.server.messaging.PiggybackedExchangeFilter; -import com.mbed.coap.server.messaging.RequestTagSupplier; -import com.mbed.coap.server.messaging.RetransmissionFilter; +import com.mbed.coap.server.messaging.*; import com.mbed.coap.server.observe.NotificationsReceiver; import com.mbed.coap.server.observe.ObservationsStore; import com.mbed.coap.transmission.RetransmissionBackOff; import com.mbed.coap.transport.CoapTransport; +import com.mbed.coap.transport.LoggingCoapTransport; import com.mbed.coap.utils.Filter; import com.mbed.coap.utils.Service; import com.mbed.coap.utils.Timer; + import java.io.IOException; import java.net.InetSocketAddress; import java.time.Duration; @@ -62,6 +43,12 @@ import java.util.function.Supplier; import java.util.stream.Stream; +import static com.mbed.coap.transport.TransportContext.RESPONSE_TIMEOUT; +import static com.mbed.coap.utils.Timer.toTimer; +import static com.mbed.coap.utils.Validations.require; +import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.toList; + public final class CoapServerBuilder { private static final long DELAYED_TRANSACTION_TIMEOUT_MS = 120000; //2 minutes @@ -80,9 +67,11 @@ public final class CoapServerBuilder { private int maxQueueSize = 100; private Filter.SimpleFilter outboundFilter = Filter.identity(); private Filter.SimpleFilter routeFilter = Filter.identity(); + private Filter.SimpleFilter requestFilter = Filter.identity(); private NotificationsReceiver notificationsReceiver = NotificationsReceiver.REJECT_ALL; private ObservationsStore observationStore = ObservationsStore.ALWAYS_EMPTY; private RequestTagSupplier requestTagSupplier = RequestTagSupplier.createSequential(); + private Boolean isTransportLoggingEnabled = true; CoapServerBuilder() { } @@ -118,6 +107,11 @@ public CoapServerBuilder routeFilter(Filter.SimpleFilter requestFilter) { + this.requestFilter = requireNonNull(requestFilter); + return this; + } + public CoapServerBuilder outboundFilter(Filter.SimpleFilter outboundFilter) { this.outboundFilter = requireNonNull(outboundFilter); return this; @@ -216,14 +210,19 @@ public CoapServerBuilder requestTagSupplier(RequestTagSupplier requestTagSupplie return this; } + public CoapServerBuilder transportLogging(Boolean transportLogging) { + this.isTransportLoggingEnabled = requireNonNull(transportLogging); + return this; + } + public CoapServer build() { - CoapTransport coapTransport = requireNonNull(this.coapTransport.get(), "Missing transport"); + CoapTransport realTransport = requireNonNull(this.coapTransport.get(), "Missing transport"); + CoapTransport coapTransport = isTransportLoggingEnabled ? new LoggingCoapTransport(realTransport) : realTransport; final boolean stopExecutor = scheduledExecutorService == null; final ScheduledExecutorService effectiveExecutorService = scheduledExecutorService != null ? scheduledExecutorService : Executors.newSingleThreadScheduledExecutor(); Timer timer = toTimer(effectiveExecutorService); - Service sender = packet -> coapTransport.sendPacket(packet) - .whenComplete((__, throwable) -> logSent(packet, throwable)); + Service sender = coapTransport::sendPacket; // OUTBOUND ExchangeFilter exchangeFilter = new ExchangeFilter(); @@ -259,6 +258,7 @@ public CoapServer build() { DuplicateDetector duplicateDetector = new DuplicateDetector(duplicateDetectorCache, duplicatedCoapMessageCallback); Service inboundService = duplicateDetector .andThen(new CoapRequestConverter(midSupplier)) + .andThen(requestFilter) .andThen(new RescueFilter()) .andThen(new CriticalOptionVerifier()) .andThen(new BlockWiseIncomingFilter(capabilities(), maxIncomingBlockTransferSize)) @@ -295,5 +295,4 @@ public CoapServerGroup buildGroup(int size) { return new CoapServerGroup(servers); } - } diff --git a/coap-core/src/main/java/com/mbed/coap/server/messaging/CoapDispatcher.java b/coap-core/src/main/java/com/mbed/coap/server/messaging/CoapDispatcher.java index 87d1a7af..5b4aeb9d 100644 --- a/coap-core/src/main/java/com/mbed/coap/server/messaging/CoapDispatcher.java +++ b/coap-core/src/main/java/com/mbed/coap/server/messaging/CoapDispatcher.java @@ -15,18 +15,19 @@ */ package com.mbed.coap.server.messaging; -import static com.mbed.coap.transport.CoapTransport.logReceived; -import static com.mbed.coap.utils.FutureHelpers.logError; -import static com.mbed.coap.utils.FutureHelpers.logErrorIgnoreCancelled; -import static java.util.Objects.requireNonNull; import com.mbed.coap.packet.CoapPacket; import com.mbed.coap.packet.MessageType; import com.mbed.coap.packet.SeparateResponse; import com.mbed.coap.utils.Service; -import java.util.function.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.function.Function; + +import static com.mbed.coap.utils.FutureHelpers.logError; +import static com.mbed.coap.utils.FutureHelpers.logErrorIgnoreCancelled; +import static java.util.Objects.requireNonNull; + public final class CoapDispatcher { private static final Logger LOGGER = LoggerFactory.getLogger(CoapDispatcher.class); @@ -38,8 +39,8 @@ public final class CoapDispatcher { private final Function handleSeparateResponse; public CoapDispatcher(Service sender, - Service observationHandler, Service inboundService, - Function handleResponse, Function handleSeparateResponse) { + Service observationHandler, Service inboundService, + Function handleResponse, Function handleSeparateResponse) { this.sender = sender; this.observationHandler = requireNonNull(observationHandler); @@ -49,7 +50,6 @@ public CoapDispatcher(Service sender, } public void handle(CoapPacket packet) { - logReceived(packet); if (handlePing(packet)) { return; } diff --git a/coap-core/src/main/java/com/mbed/coap/transport/CoapTransport.java b/coap-core/src/main/java/com/mbed/coap/transport/CoapTransport.java index 8e30325a..30015073 100644 --- a/coap-core/src/main/java/com/mbed/coap/transport/CoapTransport.java +++ b/coap-core/src/main/java/com/mbed/coap/transport/CoapTransport.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,15 +16,12 @@ package com.mbed.coap.transport; import com.mbed.coap.packet.CoapPacket; + import java.io.IOException; import java.net.InetSocketAddress; import java.util.concurrent.CompletableFuture; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public interface CoapTransport { - Logger LOGGER = LoggerFactory.getLogger(CoapTransport.class); - void start() throws IOException; void stop(); @@ -34,30 +31,4 @@ public interface CoapTransport { CompletableFuture receive(); InetSocketAddress getLocalSocketAddress(); - - static void logSent(CoapPacket packet, Throwable maybeError) { - if (maybeError != null) { - LOGGER.warn("[{}] CoAP sent failed [{}] {}", packet.getRemoteAddrString(), packet.toString(false, false, false, true), maybeError.toString()); - return; - } - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("CoAP sent [{}]", packet.toString(true)); - } else if (LOGGER.isDebugEnabled()) { - LOGGER.debug("CoAP sent [{}]", packet.toString(false)); - } else if (LOGGER.isInfoEnabled()) { - LOGGER.info("[{}] CoAP sent [{}]", packet.getRemoteAddrString(), packet.toString(false, false, false, true)); - } - } - - static void logReceived(CoapPacket packet) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("CoAP received [{}]", packet.toString(true)); - } else if (LOGGER.isDebugEnabled()) { - LOGGER.debug("[{}] CoAP received [{}]", packet.getRemoteAddrString(), packet.toString(false)); - } else if (LOGGER.isInfoEnabled()) { - LOGGER.info("[{}] CoAP received [{}]", packet.getRemoteAddrString(), packet.toString(false, false, false, true)); - } - } - } diff --git a/coap-core/src/main/java/com/mbed/coap/transport/LoggingCoapTransport.java b/coap-core/src/main/java/com/mbed/coap/transport/LoggingCoapTransport.java new file mode 100644 index 00000000..74e1043f --- /dev/null +++ b/coap-core/src/main/java/com/mbed/coap/transport/LoggingCoapTransport.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2022-2024 java-coap contributors (https://github.com/open-coap/java-coap) + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mbed.coap.transport; + +import com.mbed.coap.packet.CoapPacket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.CompletableFuture; + +public class LoggingCoapTransport implements CoapTransport { + private static Logger LOGGER = LoggerFactory.getLogger(LoggingCoapTransport.class); + + private final CoapTransport transport; + + public LoggingCoapTransport(CoapTransport transport) { + this.transport = transport; + } + + @Override + public void start() throws IOException { + transport.start(); + } + + @Override + public void stop() { + transport.stop(); + } + + @Override + public CompletableFuture sendPacket(CoapPacket coapPacket) { + return transport.sendPacket(coapPacket).whenComplete((sent, error) -> { + logSent(coapPacket, error); + }); + } + + @Override + public CompletableFuture receive() { + return transport.receive().whenComplete((packet, __) -> { + if (packet != null) { + logReceived(packet); + } + }); + } + + @Override + public InetSocketAddress getLocalSocketAddress() { + return transport.getLocalSocketAddress(); + } + + private void logSent(CoapPacket packet, Throwable maybeError) { + if (maybeError != null) { + LOGGER.warn("[{}] CoAP sent failed [{}] {}", packet.getRemoteAddrString(), packet.toString(false, false, false, true), maybeError.toString()); + return; + } + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("CoAP sent [{}]", packet.toString(true)); + } else if (LOGGER.isDebugEnabled()) { + LOGGER.debug("CoAP sent [{}]", packet.toString(false)); + } else if (LOGGER.isInfoEnabled()) { + LOGGER.info("[{}] CoAP sent [{}]", packet.getRemoteAddrString(), packet.toString(false, false, false, true)); + } + } + + private void logReceived(CoapPacket packet) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("CoAP received [{}]", packet.toString(true)); + } else if (LOGGER.isDebugEnabled()) { + LOGGER.debug("[{}] CoAP received [{}]", packet.getRemoteAddrString(), packet.toString(false)); + } else if (LOGGER.isInfoEnabled()) { + LOGGER.info("[{}] CoAP received [{}]", packet.getRemoteAddrString(), packet.toString(false, false, false, true)); + } + } +} diff --git a/coap-core/src/test/java/com/mbed/coap/server/CoapRequestLoggerTest.java b/coap-core/src/test/java/com/mbed/coap/server/CoapRequestLoggerTest.java new file mode 100644 index 00000000..b95d16a8 --- /dev/null +++ b/coap-core/src/test/java/com/mbed/coap/server/CoapRequestLoggerTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022-2024 java-coap contributors (https://github.com/open-coap/java-coap) + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mbed.coap.server; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; +import com.mbed.coap.packet.CoapRequest; +import com.mbed.coap.packet.CoapResponse; +import com.mbed.coap.utils.Filter; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; + +import java.net.InetSocketAddress; + +import static com.mbed.coap.packet.CoapRequest.get; +import static com.mbed.coap.utils.CoapRequestBuilderFilter.REQUEST_BUILDER_FILTER; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CoapRequestLoggerTest { + private Logger logger = (Logger) LoggerFactory.getLogger(CoapRequestLoggerTest.class); + private CoapRequestLogger.CoapRequestLoggerBuilder loggerFilterBuilder = CoapRequestLogger.builder().logger(logger); + private ListAppender listAppender = new ListAppender<>(); + + @BeforeEach + public void beforeEach() { + logger.addAppender(listAppender); + listAppender.list.clear(); + listAppender.start(); + } + + @Test + void shouldLogRequestAndResponseWithDefaultMessage() { + // given + Filter filter = REQUEST_BUILDER_FILTER.andThen(loggerFilterBuilder.build()); + filter.apply( + get("/"), __ -> CoapResponse.ok().toFuture() + ); + + // then + ILoggingEvent logEvent = listAppender.list.get(0); + assertEquals(Level.INFO, logEvent.getLevel()); + assertTrue(logEvent.getMessage().contains("GET")); + assertTrue(logEvent.getMessage().contains("205")); + } + + @Test + void shouldLogRequestAndResponseWithCustomParameters() { + // given + Filter filter = REQUEST_BUILDER_FILTER.andThen( + loggerFilterBuilder.mdc("callerId", __ -> "ASDF") + .level(org.slf4j.event.Level.DEBUG) + .formatter((req, resp) -> "[" + req.getPeerAddress() + "] " + req.getMethod() + " " + req.options().getUriPath() + " -> " + resp.getCode().codeToString()) + .build() + ); + filter.apply( + get("/dupa").address(new InetSocketAddress("1.1.1.1", 31337)), __ -> CoapResponse.ok().toFuture() + ); + + // then + ILoggingEvent logEvent = listAppender.list.get(0); + assertEquals(Level.DEBUG, logEvent.getLevel()); + assertEquals(logEvent.getMDCPropertyMap().get("callerId"), "ASDF"); + assertEquals(logEvent.getMessage(), "[/1.1.1.1:31337] GET /dupa -> 205"); + } + +} diff --git a/coap-tcp/src/main/java/com/mbed/coap/server/CoapServerBuilderForTcp.java b/coap-tcp/src/main/java/com/mbed/coap/server/CoapServerBuilderForTcp.java index 97953b26..33d1928a 100644 --- a/coap-tcp/src/main/java/com/mbed/coap/server/CoapServerBuilderForTcp.java +++ b/coap-tcp/src/main/java/com/mbed/coap/server/CoapServerBuilderForTcp.java @@ -16,36 +16,27 @@ */ package com.mbed.coap.server; -import static com.mbed.coap.transport.CoapTransport.logSent; -import static java.util.Objects.requireNonNull; import com.mbed.coap.client.CoapClient; -import com.mbed.coap.packet.BlockSize; -import com.mbed.coap.packet.CoapPacket; -import com.mbed.coap.packet.CoapRequest; -import com.mbed.coap.packet.CoapResponse; -import com.mbed.coap.packet.CoapTcpPacketConverter; -import com.mbed.coap.packet.Code; -import com.mbed.coap.packet.SeparateResponse; +import com.mbed.coap.packet.*; import com.mbed.coap.server.block.BlockWiseIncomingFilter; import com.mbed.coap.server.block.BlockWiseNotificationFilter; import com.mbed.coap.server.block.BlockWiseOutgoingFilter; import com.mbed.coap.server.filter.CongestionControlFilter; -import com.mbed.coap.server.messaging.Capabilities; -import com.mbed.coap.server.messaging.CapabilitiesStorage; -import com.mbed.coap.server.messaging.CapabilitiesStorageImpl; -import com.mbed.coap.server.messaging.CoapTcpDispatcher; -import com.mbed.coap.server.messaging.PayloadSizeVerifier; -import com.mbed.coap.server.messaging.TcpExchangeFilter; +import com.mbed.coap.server.messaging.*; import com.mbed.coap.server.observe.NotificationsReceiver; import com.mbed.coap.server.observe.ObservationsStore; import com.mbed.coap.transport.CoapTcpTransport; +import com.mbed.coap.transport.LoggingCoapTransport; import com.mbed.coap.utils.Filter; import com.mbed.coap.utils.Service; + import java.io.IOException; import java.net.InetSocketAddress; import java.util.Objects; import java.util.function.Function; +import static java.util.Objects.requireNonNull; + public class CoapServerBuilderForTcp { private CoapTcpTransport coapTransport; private Service route = RouterService.NOT_FOUND_SERVICE; @@ -58,6 +49,7 @@ public class CoapServerBuilderForTcp { private Filter.SimpleFilter routeFilter = Filter.identity(); private NotificationsReceiver notificationsReceiver = NotificationsReceiver.REJECT_ALL; private ObservationsStore observationsStore = ObservationsStore.ALWAYS_EMPTY; + private Boolean isTransportLoggingEnabled = true; CoapServerBuilderForTcp() { csmStorage = new CapabilitiesStorageImpl(); @@ -129,14 +121,17 @@ public CoapServerBuilderForTcp observationsStore(ObservationsStore observationsS return this; } + public CoapServerBuilderForTcp transportLogging(Boolean transportLogging) { + this.isTransportLoggingEnabled = requireNonNull(transportLogging); + return this; + } + public CoapClient buildClient(InetSocketAddress target) throws IOException { return CoapClient.create(target, build().start(), r -> r.getCode() == Code.C703_PONG); } public CoapServer build() { - Service sender = packet -> coapTransport - .sendPacket(packet) - .whenComplete((__, throwable) -> logSent(packet, throwable)); + Service sender = (isTransportLoggingEnabled ? new LoggingCoapTransport(coapTransport) : coapTransport)::sendPacket; // NOTIFICATION Service sendNotification = new NotificationValidator() @@ -182,5 +177,4 @@ public CoapServer build() { private boolean hasRoute() { return !Objects.equals(route, RouterService.NOT_FOUND_SERVICE); } - } diff --git a/coap-tcp/src/main/java/com/mbed/coap/server/messaging/CoapTcpDispatcher.java b/coap-tcp/src/main/java/com/mbed/coap/server/messaging/CoapTcpDispatcher.java index 69b6f07d..7d978132 100644 --- a/coap-tcp/src/main/java/com/mbed/coap/server/messaging/CoapTcpDispatcher.java +++ b/coap-tcp/src/main/java/com/mbed/coap/server/messaging/CoapTcpDispatcher.java @@ -15,23 +15,17 @@ */ package com.mbed.coap.server.messaging; -import static com.mbed.coap.transport.CoapTransport.logReceived; -import static com.mbed.coap.utils.FutureHelpers.logError; -import com.mbed.coap.packet.CoapPacket; -import com.mbed.coap.packet.CoapRequest; -import com.mbed.coap.packet.CoapResponse; -import com.mbed.coap.packet.Code; -import com.mbed.coap.packet.Opaque; -import com.mbed.coap.packet.SeparateResponse; -import com.mbed.coap.packet.SignalingOptions; -import com.mbed.coap.packet.SignallingHeaderOptions; +import com.mbed.coap.packet.*; import com.mbed.coap.transport.CoapTcpListener; import com.mbed.coap.utils.Service; -import java.net.InetSocketAddress; -import java.util.function.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.net.InetSocketAddress; +import java.util.function.Function; + +import static com.mbed.coap.utils.FutureHelpers.logError; + public class CoapTcpDispatcher implements CoapTcpListener { private static final Logger LOGGER = LoggerFactory.getLogger(CoapTcpDispatcher.class); @@ -43,8 +37,8 @@ public class CoapTcpDispatcher implements CoapTcpListener { private final Function observationHandler; public CoapTcpDispatcher(Service sender, CapabilitiesStorage csmStorage, Capabilities ownCapability, - Service inboundService, Function outboundHandler, - Function observationHandler) { + Service inboundService, Function outboundHandler, + Function observationHandler) { this.csmStorage = csmStorage; this.ownCapability = ownCapability; this.sender = sender; @@ -54,8 +48,6 @@ public CoapTcpDispatcher(Service sender, CapabilitiesStorag } public void handle(CoapPacket packet) { - logReceived(packet); - // EMPTY (healthcheck) if (packet.getCode() == null && packet.getMethod() == null) { // ignore