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..38134387 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,7 +16,6 @@ */ 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; @@ -50,6 +49,7 @@ 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; @@ -80,9 +80,11 @@ public final class CoapServerBuilder { private int maxQueueSize = 100; private Filter.SimpleFilter outboundFilter = Filter.identity(); private Filter.SimpleFilter routeFilter = Filter.identity(); + private Filter.SimpleFilter inboundRequestFilter = 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 +120,11 @@ public CoapServerBuilder routeFilter(Filter.SimpleFilter inboundRequestFilter) { + this.inboundRequestFilter = requireNonNull(inboundRequestFilter); + return this; + } + public CoapServerBuilder outboundFilter(Filter.SimpleFilter outboundFilter) { this.outboundFilter = requireNonNull(outboundFilter); return this; @@ -216,14 +223,19 @@ public CoapServerBuilder requestTagSupplier(RequestTagSupplier requestTagSupplie return this; } + public CoapServerBuilder transportLogging(boolean isTransportLoggingEnabled) { + this.isTransportLoggingEnabled = isTransportLoggingEnabled; + 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 +271,7 @@ public CoapServer build() { DuplicateDetector duplicateDetector = new DuplicateDetector(duplicateDetectorCache, duplicatedCoapMessageCallback); Service inboundService = duplicateDetector .andThen(new CoapRequestConverter(midSupplier)) + .andThen(inboundRequestFilter) .andThen(new RescueFilter()) .andThen(new CriticalOptionVerifier()) .andThen(new BlockWiseIncomingFilter(capabilities(), maxIncomingBlockTransferSize)) @@ -295,5 +308,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..c8e4f6ae 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,7 +15,6 @@ */ 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; @@ -49,7 +48,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..66707b8c 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 @@ -19,12 +19,8 @@ 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 +30,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..c9b303ab --- /dev/null +++ b/coap-core/src/main/java/com/mbed/coap/transport/LoggingCoapTransport.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.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 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-tcp/src/main/java/com/mbed/coap/server/CoapServerBuilderForTcp.java b/coap-tcp/src/main/java/com/mbed/coap/server/CoapServerBuilderForTcp.java index 97953b26..ba5cf921 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,7 +16,6 @@ */ 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; @@ -39,6 +38,7 @@ 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; @@ -58,6 +58,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 +130,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 +186,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..74c95e6c 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,7 +15,6 @@ */ 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; @@ -54,8 +53,6 @@ public CoapTcpDispatcher(Service sender, CapabilitiesStorag } public void handle(CoapPacket packet) { - logReceived(packet); - // EMPTY (healthcheck) if (packet.getCode() == null && packet.getMethod() == null) { // ignore