server: support for encoded audit headers
Support utf-8 characters in audit headers by allowing them to be sent encoded.
The header X-Killbill-Encoding must be specified (only base64 is supported at the moment).
package org.killbill.billing.server.filters;
import java.io.OutputStream;
+import java.util.Base64;
import java.util.List;
import java.util.concurrent.TimeUnit;
+import java.util.function.BiFunction;
import javax.inject.Singleton;
import javax.ws.rs.container.ContainerRequestContext;
@@ -31,10 +33,14 @@ import org.glassfish.jersey.server.ContainerException;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.ContainerResponse;
import org.glassfish.jersey.server.spi.ContainerResponseWriter;
+import org.killbill.billing.jaxrs.resources.JaxrsResource;
import org.killbill.billing.util.UUIDs;
import org.killbill.commons.request.Request;
import org.killbill.commons.request.RequestData;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+
@Singleton
public class RequestDataFilter implements ContainerRequestFilter, ContainerResponseFilter {
@@ -42,11 +48,46 @@ public class RequestDataFilter implements ContainerRequestFilter, ContainerRespo
private static final String LEGACY_REQUEST_ID_HEADER = "X-Killbill-Request-Id-Req";
+ private static final String KILL_BILL_ENCODING_HEADER = "X-Killbill-Encoding";
+
@Override
public void filter(final ContainerRequestContext requestContext) {
final List<String> requestIdHeaderRequests = getRequestId(requestContext);
final String requestId = (requestIdHeaderRequests == null || requestIdHeaderRequests.isEmpty()) ? UUIDs.randomUUID().toString() : requestIdHeaderRequests.get(0);
Request.setPerThreadRequestData(new RequestData(requestId));
+
+ final List<String> kbEncodingHeaders = requestContext.getHeaders().get(KILL_BILL_ENCODING_HEADER);
+ final String kbEncodingHeader = (kbEncodingHeaders == null || kbEncodingHeaders.isEmpty()) ? null : kbEncodingHeaders.get(0);
+ if (kbEncodingHeader != null) {
+ requestContext.getHeaders()
+ .replaceAll(new BiFunction<String, List<String>, List<String>>() {
+ @Override
+ public List<String> apply(final String k, final List<String> v) {
+ if (k.equalsIgnoreCase(JaxrsResource.HDR_COMMENT) ||
+ k.equalsIgnoreCase(JaxrsResource.HDR_REASON) ||
+ k.equalsIgnoreCase(JaxrsResource.HDR_CREATED_BY)) {
+ return Lists.transform(v,
+ new Function<String, String>() {
+ @Override
+ public String apply(final String input) {
+ if ("base64".equalsIgnoreCase(kbEncodingHeader)) {
+ try {
+ return new String(Base64.getDecoder().decode(input));
+ } catch (final IllegalArgumentException e) {
+ // Not Base64 after all? Be lenient...
+ return input;
+ }
+ } else {
+ return input;
+ }
+ }
+ });
+ } else {
+ return v;
+ }
+ }
+ });
+ }
}
@Override
