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