Hi Andriy,
Currently I create the attachment like:
ContentDisposition cd = new
ContentDisposition("form-data;name=file-0;filename="+filename);
InputStream is = new
ByteArrayInputStream(Dossier.toCSV(dossiers).getBytes(StandardCharsets.UTF_8));
Attachment att = new Attachment("root",is, cd);
Although this work (i.e. is accepted by the server) it is not the
appropriate way to generate an Attachment containing a csv file as readable
characters.
The API docs refer to using
org.apache.cxf.jaxrs.ext.multipart.AttachmentBuilder but the constructors
don't give much information.
So what would be an appropriate way to send a csv-file that would get
logged?
Regards,
J.P. Urkens
-----Original Message-----
From: Andriy Redko <[email protected]>
Sent: zondag 12 november 2023 17:15
To: Jean Pierre URKENS <[email protected]>; [email protected]
Subject: Re: Apache CXF JAXRS Logging questions
Hi Jean,
Getting back to you with the multipart logging, there are 2 parts to it: the
message content-type and boundary content-type. The message content type is
indeed multipart and is logged but it seems like the boundary content type
(uuid:4ee36a2e-8382-4ef8-878b-0aedcab77c3b) is binary, this is why it is
logged as suppressed (binary boundary content is not logged, as per
AbstractLoggingInterceptor::stripBinaryParts).
Hope it helps, thank you.
Best Regards,
Andriy Redko
> Hi Andriy,
> When sending a multipart/form-data request to a service endpoint I see the
> following in the message log:
> 2023-11-10 13:27:37,578 [T8N1TP1-4] INFO
> (SID=D04AF2A21B0DCEFFE4724AEF745B5BDF)
> (org.apache.cxf.ext.logging.slf4j.Slf4jEventSender:84) - REQ_OUT
> Address: http://L-P53-008:8085/dosis-server/csv
> HttpMethod: POST
> Content-Type: multipart/form-data;charset=UTF-8;
> boundary="uuid:4ee36a2e-8382-4ef8-878b-0aedcab77c3b"
> ExchangeId: d87098e4-fe86-4a42-8985-37a6ccc90b1d
> Headers: {Authorization=Bearer 11a5b872-be3f-49f8-a26f-fbeb9be56a66,
> Accept=*/*}
> Payload:
> --uuid:4ee36a2e-8382-4ef8-878b-0aedcab77c3b
> --- Content suppressed ---
> ----uuid:4ee36a2e-8382-4ef8-878b-0aedcab77c3b
> 2023-11-10 13:27:37,661 [T8N1TP1-4] INFO
> (SID=D04AF2A21B0DCEFFE4724AEF745B5BDF)
> (org.apache.cxf.ext.logging.slf4j.Slf4jEventSender:84) - RESP_IN
> Address: http://L-P53-008:8085/dosis-server/csv
> ResponseCode: 200
> ExchangeId: d87098e4-fe86-4a42-8985-37a6ccc90b1d
> Headers: {transfer-encoding=chunked, Date=Fri, 10 Nov 2023
> 12:27:37 GMT} I.e. the logging of the multipart form-data gets suppressed.
> I tried enabling it by setting the LoggingFeature (although according to
> the Javadoc ‘logMultipart defaults to true’) on the JAXRSClientFactoryBean
> e.g.:
> public Response dossiersOpladen(List<Dossier> dossiers, String
> filename) throws GeneralSecurityException, AuthorizationException,
> DosisCommunicationException, BusinessException {
> try {
> //Create the web client
> String baseAddress =
> Configuration.getInstance().getItem("dosis.service.base.uri");
> clientProxy =
> getThreadsafeProxy(baseAddress+"/csv");
> Client client = WebClient.client(clientProxy);
> WebClient webClient =
> WebClient.fromClient(client);
>
> WebClient.getConfig(webClient).getHttpConduit().getClient().setReceiveTimeout(60000L);
>
> webClient.type(MediaType.MULTIPART_FORM_DATA_TYPE.withCharset(Standard
> Charsets.UTF_8.name()));
>
> //Authorize API client by adding an appropriate
> authorization header
> authorizationHandler.authorize(webClient);
>
> //POST the request
> log.info("Uploading dossiers from csv");
> ContentDisposition cd = new
> ContentDisposition("form-data;name=file-0;filename="+filename);
> InputStream is = new
> ByteArrayInputStream(Dossier.toCSV(dossiers).getBytes(StandardCharsets.UTF_8));
> Attachment att = new Attachment("root",is, cd);
> return webClient.post(new MultipartBody(att));
> } catch (JsonProcessingException e) {
> throw new BusinessException("Exception using REST
> service: "+e.getMessage(),e);
> }
> }
> private static DosisService getThreadsafeProxy(String baseAddress)
> throws GeneralSecurityException {
> JacksonJsonProvider jjProvider = new
> JacksonJsonProvider(new CustomObjectMapper());
> List<Object> providers = Arrays.asList(new
> MultipartProvider(), jjProvider);
>
> final JAXRSClientFactoryBean factory = new
> JAXRSClientFactoryBean();
> factory.setAddress(baseAddress);
> factory.setServiceClass(DosisService.class);
> factory.setProviders(providers);
> factory.getOutInterceptors().add(new
> LoggingOutInterceptor());
> factory.getInInterceptors().add(new
> LoggingInInterceptor());
> factory.setThreadSafe(true);
>
> LoggingFeature feature = new LoggingFeature();
> feature.setLogMultipart(true);
> feature.setLogBinary(true);
> factory.setFeatures(Arrays.asList(feature));
> DosisService api = factory.create(DosisService.class);
> return api;
> }
> But still it doesn’t show anything. So how can I get this logged (for
> testing purposes)?
> Another question: Is it possible to get REST messages for different
> endpoints to be logged to different files?
> Currently I just include the Logging[In|Out]Interceptor and have logging
> set through Log4J:
> # Logging for CXF webservices
> log4j.appender.WS=org.apache.log4j.DailyRollingFileAppender
> log4j.appender.WS.File=${catalina.base}/logs/kmopFrontend-ws.log
> log4j.appender.WS.encoding=UTF-8
> log4j.appender.WS.datePattern=yyyy-MM-dd
> log4j.appender.WS.layout=org.apache.log4j.PatternLayout
> log4j.appender.WS.layout.ConversionPattern=%d{ISO8601} [%t] %-5p
> %X{sessionId} (%C:%L) - %m%n log4j.additivity.org.apache.cxf=false
> log4j.logger.org.apache.cxf=INFO,WS
> This however doesn’t allow me to differentiate between (completely
> different and unrelated) service endpoints. Everything gets logged in the
> same file.
> Regards,
> J.P. Urkens