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}