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