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    if (logger != null) {
047      logger.logRequest(request.method(), request.url().toString(), hdrs, cnt);
048    }
049
050    // Log Response
051    Response response = null;
052    response = chain.proceed(chain.request());
053
054    MediaType contentType = null;
055    byte[] bodyBytes = null;
056    if (response.body() != null) {
057      contentType = response.body().contentType();
058      bodyBytes = response.body().bytes();
059    }
060
061    // Get Headers as List
062    List<String> headerList = new ArrayList<>();
063    Map<String, List<String>> headerMap = response.headers().toMultimap();
064    headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value)));
065
066    if (logger != null) {
067      logger.logResponse(Integer.toString(response.code()), headerList, bodyBytes, 0);
068    }
069
070    // Reading byte[] clears body. Need to recreate.
071    ResponseBody body = ResponseBody.create(bodyBytes, contentType);
072    return response.newBuilder().body(body).build();
073  }
074}