001package org.hl7.fhir.r4.utils.client.network;
002
003import java.io.IOException;
004import java.util.ArrayList;
005import java.util.List;
006import java.util.Map;
007
008import javax.annotation.Nonnull;
009
010import org.hl7.fhir.utilities.ToolingClientLogger;
011
012import okhttp3.Interceptor;
013import okhttp3.MediaType;
014import okhttp3.Request;
015import okhttp3.Response;
016import okhttp3.ResponseBody;
017import okio.Buffer;
018
019public class FhirLoggingInterceptor implements Interceptor {
020
021  private ToolingClientLogger logger;
022
023  public FhirLoggingInterceptor(ToolingClientLogger logger) {
024    this.logger = logger;
025  }
026
027  public FhirLoggingInterceptor setLogger(ToolingClientLogger logger) {
028    this.logger = logger;
029    return this;
030  }
031
032  @Override
033  public Response intercept(@Nonnull Interceptor.Chain chain) throws IOException {
034    // Log Request
035    Request request = chain.request();
036    List<String> hdrs = new ArrayList<>();
037    for (String s : request.headers().toString().split("\\n")) {
038      hdrs.add(s.trim());
039    }
040    byte[] cnt = null;
041    if (request.body() != null) {
042      Buffer buf = new Buffer();
043      request.body().writeTo(buf);
044      cnt = buf.readByteArray();
045    }
046    logger.logRequest(request.method(), request.url().toString(), hdrs, cnt);
047
048    // Log Response
049    Response response = null;
050    response = chain.proceed(chain.request());
051
052    MediaType contentType = null;
053    byte[] bodyBytes = null;
054    if (response.body() != null) {
055      contentType = response.body().contentType();
056      bodyBytes = response.body().bytes();
057    }
058
059    // Get Headers as List
060    List<String> headerList = new ArrayList<>();
061    Map<String, List<String>> headerMap = response.headers().toMultimap();
062    headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
063
064    logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes);
065
066    // Reading byte[] clears body. Need to recreate.
067    ResponseBody body = ResponseBody.create(bodyBytes, contentType);
068    return response.newBuilder().body(body).build();
069  }
070}