diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java index 4f7c7c015a6..ff2a52c2b6f 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java @@ -32,6 +32,7 @@ import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; import org.apache.cxf.phase.AbstractPhaseInterceptor; public abstract class AbstractLoggingInterceptor extends AbstractPhaseInterceptor { @@ -63,7 +64,8 @@ public AbstractLoggingInterceptor(String phase, LogEventSender sender) { } protected static boolean isLoggingDisabledNow(Message message) throws Fault { - Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP); + final Object liveLoggingProp = message.getContextualProperty(LIVE_LOGGING_PROP + "." + + MessageUtils.isRequestor(message)); return liveLoggingProp != null && PropertyUtils.isFalse(liveLoggingProp); } diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java index 436bbf3d16d..f29ce04d145 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingInInterceptor.java @@ -34,6 +34,7 @@ import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.io.CachedWriter; import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.apache.cxf.phase.PhaseInterceptor; @@ -87,7 +88,7 @@ public void handleMessage(Message message) throws Fault { //ensure only logging once for a certain message //this can prevent message logging again when fault //happen after PRE_INVOKE phase(rewind calls into LoggingInFaultInterceptor) - message.put(LIVE_LOGGING_PROP, Boolean.FALSE); + message.put(LIVE_LOGGING_PROP + "." + MessageUtils.isRequestor(message), Boolean.FALSE); } createExchangeId(message); final LogEvent event = eventMapper.map(message, sensitiveProtocolHeaderNames); diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java index 7e68a7c5cca..78bf5c667d6 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingOutInterceptor.java @@ -37,6 +37,7 @@ import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.io.CachedOutputStreamCallback; import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; import org.apache.cxf.phase.Phase; /** @@ -65,7 +66,7 @@ public void handleMessage(Message message) throws Fault { //ensure only logging once for a certain message //this can prevent message logging again when fault //happen after PRE_STREAM phase(LoggingOutInterceptor is called both in out chain and fault out chain) - message.put(LIVE_LOGGING_PROP, Boolean.FALSE); + message.put(LIVE_LOGGING_PROP + "." + MessageUtils.isRequestor(message), Boolean.FALSE); } createExchangeId(message); final OutputStream os = message.getContent(OutputStream.class); diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java index 9c563cb37fa..694275bc051 100644 --- a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java +++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/JaxWsClientTest.java @@ -22,6 +22,7 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.net.URL; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -44,6 +45,9 @@ import jakarta.xml.ws.handler.soap.SOAPMessageContext; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.ClientImpl; +import org.apache.cxf.ext.logging.LoggingFeature; +import org.apache.cxf.ext.logging.event.LogEvent; +import org.apache.cxf.ext.logging.event.LogEventSender; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.interceptor.Fault; @@ -58,10 +62,12 @@ import org.apache.cxf.service.model.EndpointInfo; import org.apache.cxf.service.model.MessagePartInfo; import org.apache.cxf.transport.Destination; +import org.apache.cxf.transport.local.LocalTransportFactory; import org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean; import org.apache.hello_world_soap_http.BadRecordLitFault; import org.apache.hello_world_soap_http.Greeter; import org.apache.hello_world_soap_http.GreeterImpl; +import org.apache.hello_world_soap_http.types.SayHi; import org.junit.Before; import org.junit.Test; @@ -249,6 +255,7 @@ public void testEndpoint() throws Exception { EndpointInfo ei = service.getServiceInfos().get(0).getEndpoint(new QName(namespace, "SoapPort")); JaxWsEndpointImpl endpoint = new JaxWsEndpointImpl(getBus(), service, ei); + getBus().setFeatures(List.of(new LoggingFeature())); ClientImpl client = new ClientImpl(getBus(), endpoint); BindingOperationInfo bop = ei.getBinding().getOperation(new QName(namespace, "sayHi")); @@ -305,6 +312,42 @@ public void handleMessage(Message message) throws Fault { } + @Test + public void testEndpointWithLogging() throws Exception { + GreeterImpl service = new GreeterImpl(); + String namespace = "http://apache.org/hello_world_soap_http"; + try (EndpointImpl ep = new EndpointImpl(getBus(), service, (String) null)) { + ep.publish("local://localhost:9092/hello"); + + EndpointInfo ei = ep.getService().getServiceInfos().get(0).getEndpoint(new QName(namespace, "SoapPort")); + JaxWsEndpointImpl endpoint = new JaxWsEndpointImpl(getBus(), ep.getService(), ei); + + final List events = new ArrayList<>(); + final LoggingFeature loggingFeature = new LoggingFeature(); + loggingFeature.setSender(new LogEventSender() { + @Override + public void send(LogEvent event) { + events.add(event); + } + }); + getBus().setFeatures(List.of(loggingFeature)); + + ClientImpl client = new ClientImpl(getBus(), endpoint); + client.getRequestContext().put(LocalTransportFactory.MESSAGE_INCLUDE_PROPERTIES, + Collections.singleton("org.apache.cxf.logging.enable")); + + BindingOperationInfo bop = ei.getBinding().getOperation(new QName(namespace, "sayHi")); + assertNotNull(bop); + + Object[] ret = client.invoke(bop, new Object[] {new SayHi()}, null); + assertNotNull(ret); + assertEquals("Wrong number of return objects", 1, ret.length); + + assertEquals(4, events.size()); + client.close(); + } + } + @Test public void testClientProxyFactory() { JaxWsProxyFactoryBean cf = new JaxWsProxyFactoryBean(); diff --git a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java index 01c188c96f8..b617bf0629a 100644 --- a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java +++ b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/RESTLoggingTest.java @@ -192,6 +192,31 @@ public void testEvents() throws MalformedURLException { checkResponseIn(events.get(3)); } + @Test + public void testEventsWithProxy() throws MalformedURLException { + LoggingFeature loggingFeature = new LoggingFeature(); + loggingFeature.setLogBinary(true); + TestEventSender sender = new TestEventSender(); + loggingFeature.setSender(sender); + Server server = createService(SERVICE_URI, new TestServiceRest(), loggingFeature); + server.start(); + TestService client = createClient(SERVICE_URI, TestService.class, loggingFeature); + String result = client.echo("test1"); + Assert.assertEquals("test1", result); + + List events = sender.getEvents(); + await().until(() -> events.size(), is(4)); + server.stop(); + server.destroy(); + + Assert.assertEquals(4, events.size()); + checkRequestOut(events.get(0)); + checkRequestIn(events.get(1)); + checkResponseOut(events.get(2)); + checkResponseIn(events.get(3)); + } + + private void assertContentLogged(LogEvent event) { Assert.assertNotEquals(AbstractLoggingInterceptor.CONTENT_SUPPRESSED, event.getPayload()); } @@ -200,6 +225,14 @@ private void assertContentNotLogged(LogEvent event) { Assert.assertEquals(AbstractLoggingInterceptor.CONTENT_SUPPRESSED, event.getPayload()); } + private T createClient(String serviceURI, Class contract, LoggingFeature loggingFeature) { + JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean(); + bean.setAddress(serviceURI); + bean.setFeatures(Collections.singletonList(loggingFeature)); + bean.setResourceClass(contract); + return bean.create(contract); + } + private WebClient createClient(String serviceURI, LoggingFeature loggingFeature) { JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean(); bean.setAddress(serviceURI); diff --git a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestService.java b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestService.java new file mode 100644 index 00000000000..7cc52c738d7 --- /dev/null +++ b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestService.java @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.cxf.jaxrs.client.logging; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; + +public interface TestService { + @GET + @Path("{msg}") + @Produces("application/octet-stream") + String echo(@PathParam("msg") String msg); + + @POST + String post(String msg); +} \ No newline at end of file diff --git a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java index 1ef575e970e..f9999655428 100644 --- a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java +++ b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/logging/TestServiceRest.java @@ -18,19 +18,13 @@ */ package org.apache.cxf.jaxrs.client.logging; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; - -public class TestServiceRest { - @GET - @Path("{msg}") - public String echo(@PathParam("msg") String msg) { +public class TestServiceRest implements TestService { + @Override + public String echo(String msg) { return msg; } - @POST + @Override public String post(String msg) { return msg; }