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