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 public static final String DEFAULT_CHARSET = "UTF-8"; 021 private static final long DEFAULT_TIMEOUT = 5000; 022 private ToolingClientLogger logger; 023 private FhirLoggingInterceptor fhirLoggingInterceptor; 024 private int retryCount; 025 private long timeout = DEFAULT_TIMEOUT; 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 long getTimeout() { 055 return timeout; 056 } 057 058 public void setTimeout(long timeout) { 059 this.timeout = timeout; 060 } 061 062 public <T extends Resource> ResourceRequest<T> issueOptionsRequest(URI optionsUri, String resourceFormat, 063 String message, long timeout) throws IOException { 064 Request.Builder request = new Request.Builder().method("OPTIONS", null).url(optionsUri.toURL()); 065 066 return executeFhirRequest(request, resourceFormat, new Headers.Builder().build(), message, retryCount, timeout); 067 } 068 069 public <T extends Resource> ResourceRequest<T> issueGetResourceRequest(URI resourceUri, String resourceFormat, 070 Headers headers, String message, long timeout) throws IOException { 071 Request.Builder request = new Request.Builder().url(resourceUri.toURL()); 072 073 return executeFhirRequest(request, resourceFormat, headers, message, retryCount, timeout); 074 } 075 076 public int tester(int trytry) { 077 return 5; 078 } 079 080 public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, 081 String message, long timeout) throws IOException { 082 return issuePutRequest(resourceUri, payload, resourceFormat, new Headers.Builder().build(), message, timeout); 083 } 084 085 public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, 086 Headers headers, String message, long timeout) throws IOException { 087 if (payload == null) 088 throw new EFhirClientException("PUT requests require a non-null payload"); 089 RequestBody body = RequestBody.create(payload); 090 Request.Builder request = new Request.Builder().url(resourceUri.toURL()).put(body); 091 092 return executeFhirRequest(request, resourceFormat, headers, message, retryCount, timeout); 093 } 094 095 public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, 096 String resourceFormat, String message, long timeout) throws IOException { 097 return issuePostRequest(resourceUri, payload, resourceFormat, new Headers.Builder().build(), message, timeout); 098 } 099 100 public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, 101 String resourceFormat, Headers headers, String message, long timeout) throws IOException { 102 if (payload == null) 103 throw new EFhirClientException("POST requests require a non-null payload"); 104 RequestBody body = RequestBody.create(MediaType.parse(resourceFormat + ";charset=" + DEFAULT_CHARSET), payload); 105 Request.Builder request = new Request.Builder().url(resourceUri.toURL()).post(body); 106 107 return executeFhirRequest(request, resourceFormat, headers, message, retryCount, timeout); 108 } 109 110 public boolean issueDeleteRequest(URI resourceUri) throws IOException { 111 Request.Builder request = new Request.Builder().url(resourceUri.toURL()).delete(); 112 return executeFhirRequest(request, null, new Headers.Builder().build(), null, retryCount, timeout) 113 .isSuccessfulRequest(); 114 } 115 116 public Bundle issueGetFeedRequest(URI resourceUri, String resourceFormat) throws IOException { 117 Request.Builder request = new Request.Builder().url(resourceUri.toURL()); 118 119 return executeBundleRequest(request, resourceFormat, new Headers.Builder().build(), null, retryCount, timeout); 120 } 121 122 public Bundle issuePostFeedRequest(URI resourceUri, Map<String, String> parameters, String resourceName, 123 Resource resource, String resourceFormat) throws IOException { 124 String boundary = "----WebKitFormBoundarykbMUo6H8QaUnYtRy"; 125 byte[] payload = ByteUtils.encodeFormSubmission(parameters, resourceName, resource, boundary); 126 RequestBody body = RequestBody.create(MediaType.parse(resourceFormat + ";charset=" + DEFAULT_CHARSET), payload); 127 Request.Builder request = new Request.Builder().url(resourceUri.toURL()).post(body); 128 129 return executeBundleRequest(request, resourceFormat, new Headers.Builder().build(), null, retryCount, timeout); 130 } 131 132 public Bundle postBatchRequest(URI resourceUri, byte[] payload, String resourceFormat, String message, int timeout) 133 throws IOException { 134 if (payload == null) 135 throw new EFhirClientException("POST requests require a non-null payload"); 136 RequestBody body = RequestBody.create(MediaType.parse(resourceFormat + ";charset=" + DEFAULT_CHARSET), payload); 137 Request.Builder request = new Request.Builder().url(resourceUri.toURL()).post(body); 138 139 return executeBundleRequest(request, resourceFormat, new Headers.Builder().build(), message, retryCount, timeout); 140 } 141 142 public <T extends Resource> Bundle executeBundleRequest(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).executeAsBatch(); 148 } 149 150 public <T extends Resource> ResourceRequest<T> executeFhirRequest(Request.Builder request, String resourceFormat, 151 Headers headers, String message, int retryCount, long timeout) throws IOException { 152 return new FhirRequestBuilder(request, base).withLogger(fhirLoggingInterceptor).withResourceFormat(resourceFormat) 153 .withRetryCount(retryCount).withMessage(message) 154 .withHeaders(headers == null ? new Headers.Builder().build() : headers) 155 .withTimeout(timeout, TimeUnit.MILLISECONDS).execute(); 156 } 157}