001package org.hl7.fhir.r4.utils.client.network;
002
003import java.io.IOException;
004import java.net.URI;
005import java.util.Map;
006import java.util.concurrent.TimeUnit;
007
008import org.hl7.fhir.r4.model.Bundle;
009import org.hl7.fhir.r4.model.Resource;
010import org.hl7.fhir.r4.utils.client.EFhirClientException;
011import org.hl7.fhir.utilities.ToolingClientLogger;
012
013import okhttp3.Headers;
014import okhttp3.MediaType;
015import okhttp3.Request;
016import okhttp3.RequestBody;
017
018public class Client {
019  
020  
021
022  public static final String DEFAULT_CHARSET = "UTF-8";
023  private ToolingClientLogger logger;
024  private FhirLoggingInterceptor fhirLoggingInterceptor;
025  private int retryCount;
026  private String base;
027  
028  public String getBase() {
029    return base;
030  }
031
032  public void setBase(String base) {
033    this.base = base;
034  }
035
036
037  public ToolingClientLogger getLogger() {
038    return logger;
039  }
040
041  public void setLogger(ToolingClientLogger logger) {
042    this.logger = logger;
043    this.fhirLoggingInterceptor = new FhirLoggingInterceptor(logger);
044  }
045
046  public int getRetryCount() {
047    return retryCount;
048  }
049
050  public void setRetryCount(int retryCount) {
051    this.retryCount = retryCount;
052  }
053
054  public <T extends Resource> ResourceRequest<T> issueOptionsRequest(URI optionsUri, String resourceFormat,
055      String message, long timeout) throws IOException {
056    Request.Builder request = new Request.Builder().method("OPTIONS", null).url(optionsUri.toURL());
057
058    return executeFhirRequest(request, resourceFormat, new Headers.Builder().build(), message, retryCount, timeout);
059  }
060
061  public <T extends Resource> ResourceRequest<T> issueGetResourceRequest(URI resourceUri, String resourceFormat,
062      Headers headers, String message, long timeout) throws IOException {
063    Request.Builder request = new Request.Builder().url(resourceUri.toURL());
064
065    return executeFhirRequest(request, resourceFormat, headers, message, retryCount, timeout);
066  }
067
068  public int tester(int trytry) {
069    return 5;
070  }
071
072  public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat,
073      String message, long timeout) throws IOException {
074    return issuePutRequest(resourceUri, payload, resourceFormat, new Headers.Builder().build(), message, timeout);
075  }
076
077  public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat,
078      Headers headers, String message, long timeout) throws IOException {
079    if (payload == null)
080      throw new EFhirClientException("PUT requests require a non-null payload");
081    RequestBody body = RequestBody.create(payload);
082    Request.Builder request = new Request.Builder().url(resourceUri.toURL()).put(body);
083
084    return executeFhirRequest(request, resourceFormat, headers, message, retryCount, timeout);
085  }
086
087  public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload,
088      String resourceFormat, String message, long timeout) throws IOException {
089    return issuePostRequest(resourceUri, payload, resourceFormat, new Headers.Builder().build(), message, timeout);
090  }
091
092  public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload,
093      String resourceFormat, Headers headers, String message, long timeout) throws IOException {
094    if (payload == null)
095      throw new EFhirClientException("POST requests require a non-null payload");
096    RequestBody body = RequestBody.create(MediaType.parse(resourceFormat + ";charset=" + DEFAULT_CHARSET), payload);
097    Request.Builder request = new Request.Builder().url(resourceUri.toURL()).post(body);
098
099    return executeFhirRequest(request, resourceFormat, headers, message, retryCount, timeout);
100  }
101
102  public boolean issueDeleteRequest(URI resourceUri, int timeout) throws IOException {
103    Request.Builder request = new Request.Builder().url(resourceUri.toURL()).delete();
104    return executeFhirRequest(request, null, new Headers.Builder().build(), null, retryCount, timeout)
105        .isSuccessfulRequest();
106  }
107
108  public Bundle issueGetFeedRequest(URI resourceUri, String resourceFormat, int timeout) throws IOException {
109    Request.Builder request = new Request.Builder().url(resourceUri.toURL());
110
111    return executeBundleRequest(request, resourceFormat, new Headers.Builder().build(), null, retryCount, timeout);
112  }
113
114  public Bundle issuePostFeedRequest(URI resourceUri, Map<String, String> parameters, String resourceName,
115      Resource resource, String resourceFormat, int timeout) throws IOException {
116    String boundary = "----WebKitFormBoundarykbMUo6H8QaUnYtRy";
117    byte[] payload = ByteUtils.encodeFormSubmission(parameters, resourceName, resource, boundary);
118    RequestBody body = RequestBody.create(MediaType.parse(resourceFormat + ";charset=" + DEFAULT_CHARSET), payload);
119    Request.Builder request = new Request.Builder().url(resourceUri.toURL()).post(body);
120
121    return executeBundleRequest(request, resourceFormat, new Headers.Builder().build(), null, retryCount, timeout);
122  }
123
124  public Bundle postBatchRequest(URI resourceUri, byte[] payload, String resourceFormat, String message, int timeout)
125      throws IOException {
126    if (payload == null)
127      throw new EFhirClientException("POST requests require a non-null payload");
128    RequestBody body = RequestBody.create(MediaType.parse(resourceFormat + ";charset=" + DEFAULT_CHARSET), payload);
129    Request.Builder request = new Request.Builder().url(resourceUri.toURL()).post(body);
130
131    return executeBundleRequest(request, resourceFormat, new Headers.Builder().build(), message, retryCount, timeout);
132  }
133
134  public <T extends Resource> Bundle executeBundleRequest(Request.Builder request, String resourceFormat,
135      Headers headers, String message, int retryCount, long timeout) throws IOException {
136    return new FhirRequestBuilder(request, base).withLogger(fhirLoggingInterceptor).withResourceFormat(resourceFormat)
137        .withRetryCount(retryCount).withMessage(message)
138        .withHeaders(headers == null ? new Headers.Builder().build() : headers)
139        .withTimeout(timeout, TimeUnit.MILLISECONDS).executeAsBatch();
140  }
141
142  public <T extends Resource> ResourceRequest<T> executeFhirRequest(Request.Builder request, String resourceFormat,
143      Headers headers, String message, int retryCount, long timeout) throws IOException {
144    return new FhirRequestBuilder(request, base).withLogger(fhirLoggingInterceptor).withResourceFormat(resourceFormat)
145        .withRetryCount(retryCount).withMessage(message)
146        .withHeaders(headers == null ? new Headers.Builder().build() : headers)
147        .withTimeout(timeout, TimeUnit.MILLISECONDS).execute();
148  }
149}