Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#533 DefaultLoggerClientRequestFilter rework #534

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,27 @@
package hu.icellmobilsoft.coffee.module.mp.restclient.provider;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map.Entry;

import jakarta.annotation.Priority;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.WriterInterceptor;
import jakarta.ws.rs.ext.WriterInterceptorContext;

import hu.icellmobilsoft.coffee.cdi.logger.AppLogger;
import hu.icellmobilsoft.coffee.cdi.logger.LogProducer;
import hu.icellmobilsoft.coffee.module.mp.restclient.RestClientPriority;
import hu.icellmobilsoft.coffee.rest.log.RequestResponseLogger;
import hu.icellmobilsoft.coffee.rest.log.annotation.LogSpecifier;
import hu.icellmobilsoft.coffee.rest.log.annotation.enumeration.LogSpecifierTarget;
import hu.icellmobilsoft.coffee.rest.utils.RestLoggerUtil;
import hu.icellmobilsoft.coffee.tool.utils.stream.OutputStreamCopier;
Expand All @@ -49,7 +54,10 @@
*/
@Priority(value = RestClientPriority.REQUEST_LOG)
@Dependent
public class DefaultLoggerClientRequestFilter implements ClientRequestFilter {
public class DefaultLoggerClientRequestFilter implements ClientRequestFilter, WriterInterceptor {

@Inject
private DefaultRestClientLogContainer logContainer;

@Inject
private RequestResponseLogger requestResponseLogger;
Expand All @@ -64,8 +72,39 @@ public void filter(ClientRequestContext requestContext) throws IOException {
msg.append(">> ").append(getClass().getName()).append(" request ->\n");
msg.append(logUrl(requestContext));
msg.append(logHeader(requestContext));
msg.append(logEntity(requestContext));
LogProducer.logToAppLogger((AppLogger appLogger) -> appLogger.info(msg.toString()), DefaultLoggerClientRequestFilter.class);
logContainer.setLogBuilder(msg);
}

/** {@inheritDoc} */
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
int maxResponseEntityLogSize = RestLoggerUtil.getMaxEntityLogSize(context, LogSpecifierTarget.CLIENT_REQUEST);
if (maxResponseEntityLogSize == LogSpecifier.NO_LOG) {
context.proceed();
return;
}

OutputStream originalStream = context.getOutputStream();
byte[] entityCopy = new byte[0];
OutputStreamCopier osc = new OutputStreamCopier(originalStream);
context.setOutputStream(osc);
// elegessuk a stream-et, kozben masoljuk a tartalmat
try {
context.proceed();
} finally {
// IS: kerdeses erdemes-e vissza irni az eredeti stream-et...
context.setOutputStream(originalStream);
}
entityCopy = osc.getCopy();
MediaType mediaType = context.getMediaType();
String requestText = new String(entityCopy, StandardCharsets.UTF_8);
String requestEntity = requestResponseLogger
.printEntity(requestText, maxResponseEntityLogSize, RequestResponseLogger.REQUEST_PREFIX, true, mediaType);

// summarize from ClientRequestFilter with entityStream content
StringBuilder logBuilder = logContainer.getLogBuilder();
logBuilder.append(requestEntity.toString());
LogProducer.logToAppLogger((AppLogger appLogger) -> appLogger.info(logBuilder.toString()), DefaultLoggerClientRequestFilter.class);
}

/**
Expand Down Expand Up @@ -107,31 +146,4 @@ protected String logHeader(ClientRequestContext requestContext) throws IOExcepti
return msg.toString();
}

/**
* Logs entity, trimmed according to {@link LogSpecifierTarget#CLIENT_REQUEST}.
*
* @param requestContext
* context
* @return entity {@link String}
* @throws IOException
* exception
*/
protected String logEntity(ClientRequestContext requestContext) throws IOException {
StringBuilder msg = new StringBuilder();
Object entity = requestContext.getEntity();
MediaType mediaType = requestContext.getMediaType();
if (entity != null) {
msg.append(
requestResponseLogger.printEntity(entity, RestLoggerUtil.getMaxEntityLogSize(requestContext, LogSpecifierTarget.CLIENT_REQUEST),
RequestResponseLogger.REQUEST_PREFIX, true, mediaType));
} else {
OutputStreamCopier osc = new OutputStreamCopier(requestContext.getEntityStream());
requestContext.setEntityStream(osc);
String requestText = new String(osc.getCopy(), StandardCharsets.UTF_8);
msg.append(requestResponseLogger.printEntity(requestText,
RestLoggerUtil.getMaxEntityLogSize(requestContext, LogSpecifierTarget.CLIENT_REQUEST), RequestResponseLogger.REQUEST_PREFIX, true,
mediaType));
}
return msg.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*-
* #%L
* Coffee
* %%
* Copyright (C) 2020 - 2023 i-Cell Mobilsoft Zrt.
* %%
* 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.
* #L%
*/
package hu.icellmobilsoft.coffee.module.mp.restclient.provider;

import jakarta.enterprise.context.RequestScoped;

/**
* Log container to concatenate the filter and interceptor logs.
*
* @author czenczl
* @since 2.3.0
*/
@RequestScoped
public class DefaultRestClientLogContainer {

private StringBuilder logBuilder;

/**
* Gets the logBuilder
*
* @return the string builder
*/
public StringBuilder getLogBuilder() {
return logBuilder;
}

/**
* Sets the logbuilder
*
* @param logBuilder
* to store logs
*/
public void setLogBuilder(StringBuilder logBuilder) {
this.logBuilder = logBuilder;
}

}
8 changes: 8 additions & 0 deletions docs/en/migration/migration210to220.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,11 @@ Changes are backwards compatible doesnt need any migration.
==== Migration

Changes are backwards compatible doesnt need any migration.

=== coffee-module-base

** DefaultLoggerClientRequestFilter properly logs the outgoing entity stream.

==== Migration

Changes are backwards compatible doesnt need any migration.
8 changes: 8 additions & 0 deletions docs/hu/migration/migration210to220.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ A változtatások nem eredményeznek átállási munkálatokat, visszafelé komp

A változtatások nem eredményeznek átállási munkálatokat, visszafelé kompatibilis.

=== coffee-module-mp-rest-client

** DefaultLoggerClientRequestFilter Megfelelően logolja a kimenő entity streamet.

==== Átállás

A változtatások nem eredményeznek átállási munkálatokat, visszafelé kompatibilis.