001/*- 002 * #%L 003 * Smile CDR - CDR 004 * %% 005 * Copyright (C) 2016 - 2024 Smile CDR, Inc. 006 * %% 007 * All rights reserved. 008 * #L% 009 */ 010package ca.cdr.api.fhirgw.json; 011 012import ca.cdr.api.fhirgw.model.RetryStrategyEnum; 013import ca.cdr.api.model.json.IModelJson; 014import ca.uhn.fhir.model.api.annotation.ExampleSupplier; 015import ca.uhn.fhir.rest.api.EncodingEnum; 016import com.fasterxml.jackson.annotation.JsonProperty; 017import io.swagger.v3.oas.annotations.media.Schema; 018import org.springframework.lang.NonNull; 019 020import java.util.Arrays; 021import java.util.Collections; 022import java.util.List; 023import java.util.function.Supplier; 024 025/** 026 * Contains the definition for an individual Smile CDR FHIR Gateway target server 027 */ 028@Schema( 029 name = "GatewayTarget", 030 description = "Contains the definition for an individual Smile CDR FHIR Gateway target server") 031@ExampleSupplier(GatewayTargetJson.ExampleSupplier.class) 032public class GatewayTargetJson implements IModelJson, Cloneable { 033 034 public static final int DEFAULT_TIMEOUT = 60 * 1000; 035 public static final Boolean DEFAULT_USE_HTTP_POST_FOR_ALL_SEARCHES = Boolean.FALSE; 036 public static final Boolean DEFAULT_SERVER_CAPABILITY_STATEMENT_VALIDATION_ENABLED = Boolean.TRUE; 037 public static final Boolean DEFAULT_ALLOWED_TO_FAIL = Boolean.FALSE; 038 039 @JsonProperty("id") 040 @Schema(description = "An internal ID for the target server") 041 private String myId; 042 043 @JsonProperty("baseUrl") 044 @Schema(description = "The base URL for the target server") 045 private String myBaseUrl; 046 047 @JsonProperty("fixedEndpointUrl") 048 @Schema( 049 description = 050 "If specified, will create a mapping between the baseUrl of the target, and this endpoint. When a bundle link is received that refers to this fixed endpoint, we will associate it to this target.") 051 private String myFixedEndpointUrl; 052 053 @JsonProperty("httpBasicCredentials") 054 @Schema( 055 description = 056 "If specified, these credentials (in the form `username:password`) will be passed in all client requests to the target server") 057 private String myHttpBasicCredentials; 058 059 @JsonProperty("connectTimeoutMillis") 060 @Schema( 061 description = 062 "Specifies a connection timeout (in millis) to use for communication with the target server. Default is " 063 + DEFAULT_TIMEOUT) 064 private Integer myConnectTimeoutMillis; 065 066 @JsonProperty("socketTimeoutMillis") 067 @Schema( 068 description = 069 "Specifies a socket timeout (in millis) to use for communication with the target server. Default is " 070 + DEFAULT_TIMEOUT) 071 private Integer mySocketTimeoutMillis; 072 073 @JsonProperty("clientInterceptorClasses") 074 @Schema( 075 description = 076 "If specified, signals to FHIR Gateway to load a comma-delimited list of CLIENT_RESPONSE interceptor classes that will allow the user to overwrite the HTTP response") 077 private String myClientInterceptorClasses; 078 079 public String getClientInterceptorClasses() { 080 return myClientInterceptorClasses; 081 } 082 083 public GatewayTargetJson setClientInterceptorClasses(String myClientInterceptorClasses) { 084 this.myClientInterceptorClasses = myClientInterceptorClasses; 085 return this; 086 } 087 088 @JsonProperty("resourceIdPrefix") 089 @Schema( 090 description = 091 "If specified, provides a prefix that will be added to all resource IDs and local references for the target server before returning to the client") 092 private String myResourceIdPrefix; 093 094 @JsonProperty("useHttpPostForAllSearches") 095 @Schema( 096 description = 097 "If set to true, FHIR search and paging operations against the target server will be performed using an HTTP POST instead of a GET. Default is `false`") 098 private Boolean myUseHttpPostForAllSearches; 099 100 @JsonProperty("serverCapabilityStatementValidationEnabled") 101 @Schema( 102 description = 103 "If set to false, FHIR Gateway will not validate the target server's CapabilityStatement with a request to /metadata. Default is `true`") 104 private Boolean myServerCapabilityStatementValidationEnabled; 105 106 @JsonProperty("alternateValidationPath") 107 @Schema( 108 description = 109 "An alternate validation path which can be used to validate the target server using a HTTP GET request.") 110 private String alternateValidationPath; 111 112 @JsonProperty("headersToForward") 113 @Schema( 114 description = 115 "Any headers specified by name will be copied from the incoming client request and added to requests to the target server") 116 private List<String> myHeadersToForward; 117 118 @JsonProperty("allowedToFail") 119 @Schema( 120 description = 121 "If set to true, FHIR search operations against the target server that fail will not return an error to the client, unless all targets for a given request have failed. This flag does not apply to read routes. Default is `false`") 122 private Boolean myAllowedToFail; 123 124 @JsonProperty("forcedEncoding") 125 @Schema( 126 description = 127 "If set, any requests containing a payload will have their payload re-encoded to the defined content-type before being forwarded to the target server") 128 private EncodingEnum myForcedEncoding; 129 130 @JsonProperty("retryStrategy") 131 @Schema( 132 description = 133 "If set, failed requests to this target will be retried using the specified retry configurations.") 134 private GatewayTargetRetryStrategyJson myRetryStrategy; 135 136 public Boolean getAllowedToFail() { 137 if (myAllowedToFail == null) { 138 myAllowedToFail = DEFAULT_ALLOWED_TO_FAIL; 139 } 140 return myAllowedToFail; 141 } 142 143 public void setAllowedToFail(Boolean theAllowedToFail) { 144 myAllowedToFail = theAllowedToFail; 145 } 146 147 public List<String> getHeadersToForward() { 148 if (myHeadersToForward == null) { 149 myHeadersToForward = Collections.emptyList(); 150 } 151 return myHeadersToForward; 152 } 153 154 public void setHeadersToForward(@NonNull List<String> theHeaders) { 155 myHeadersToForward = Collections.unmodifiableList(theHeaders); 156 } 157 158 public Boolean getUseHttpPostForAllSearches() { 159 if (myUseHttpPostForAllSearches == null) { 160 myUseHttpPostForAllSearches = DEFAULT_USE_HTTP_POST_FOR_ALL_SEARCHES; 161 } 162 return myUseHttpPostForAllSearches; 163 } 164 165 public void setUseHttpPostForAllSearches(Boolean theUseHttpPostForAllSearches) { 166 myUseHttpPostForAllSearches = theUseHttpPostForAllSearches; 167 } 168 169 public Boolean getServerCapabilityStatementValidationEnabled() { 170 if (myServerCapabilityStatementValidationEnabled == null) { 171 myServerCapabilityStatementValidationEnabled = DEFAULT_SERVER_CAPABILITY_STATEMENT_VALIDATION_ENABLED; 172 } 173 return myServerCapabilityStatementValidationEnabled; 174 } 175 176 public GatewayTargetJson setServerCapabilityStatementValidationEnabled( 177 Boolean theServerCapabilityStatementValidationEnabled) { 178 myServerCapabilityStatementValidationEnabled = theServerCapabilityStatementValidationEnabled; 179 return this; 180 } 181 182 public String getAlternateValidationPath() { 183 return alternateValidationPath; 184 } 185 186 public GatewayTargetJson setAlternateValidationPath(String theAlternateValidationPath) { 187 alternateValidationPath = theAlternateValidationPath; 188 return this; 189 } 190 191 public String getResourceIdPrefix() { 192 return myResourceIdPrefix; 193 } 194 195 public GatewayTargetJson setResourceIdPrefix(String theResourceIdPrefix) { 196 myResourceIdPrefix = theResourceIdPrefix; 197 return this; 198 } 199 200 public Integer getConnectTimeoutMillis() { 201 return myConnectTimeoutMillis; 202 } 203 204 public GatewayTargetJson setConnectTimeoutMillis(Integer theConnectTimeoutMillis) { 205 myConnectTimeoutMillis = theConnectTimeoutMillis; 206 return this; 207 } 208 209 public Integer getSocketTimeoutMillis() { 210 return mySocketTimeoutMillis; 211 } 212 213 public GatewayTargetJson setSocketTimeoutMillis(Integer theSocketTimeoutMillis) { 214 mySocketTimeoutMillis = theSocketTimeoutMillis; 215 return this; 216 } 217 218 public String getHttpBasicCredentials() { 219 return myHttpBasicCredentials; 220 } 221 222 public GatewayTargetJson setHttpBasicCredentials(String theHttpBasicCredentials) { 223 myHttpBasicCredentials = theHttpBasicCredentials; 224 return this; 225 } 226 227 public String getId() { 228 return myId; 229 } 230 231 public GatewayTargetJson setId(String theId) { 232 myId = theId; 233 return this; 234 } 235 236 public String getBaseUrl() { 237 return myBaseUrl; 238 } 239 240 public GatewayTargetJson setBaseUrl(String theBaseUrl) { 241 myBaseUrl = theBaseUrl; 242 return this; 243 } 244 245 public int getConnectTimeoutOrDefault() { 246 if (getConnectTimeoutMillis() != null) { 247 return getConnectTimeoutMillis(); 248 } 249 return DEFAULT_TIMEOUT; 250 } 251 252 public int getSocketTimeoutOrDefault() { 253 if (getSocketTimeoutMillis() != null) { 254 return getSocketTimeoutMillis(); 255 } 256 return DEFAULT_TIMEOUT; 257 } 258 259 public EncodingEnum getForcedEncoding() { 260 return myForcedEncoding; 261 } 262 263 public void setForcedEncoding(EncodingEnum theForcedEncoding) { 264 myForcedEncoding = theForcedEncoding; 265 } 266 267 public GatewayTargetRetryStrategyJson getRetryStrategy() { 268 return myRetryStrategy; 269 } 270 271 public void setRetryStrategy(GatewayTargetRetryStrategyJson theRetryStrategy) { 272 myRetryStrategy = theRetryStrategy; 273 } 274 275 @Override 276 public GatewayTargetJson clone() { 277 try { 278 return (GatewayTargetJson) super.clone(); 279 } catch (CloneNotSupportedException theE) { 280 throw new UnsupportedOperationException(); 281 } 282 } 283 284 public void setFixedEndpointUrl(String theFixedTargetUrl) { 285 myFixedEndpointUrl = theFixedTargetUrl; 286 } 287 288 public String getFixedEndpointUrl() { 289 return myFixedEndpointUrl; 290 } 291 292 public static class ExampleSupplier implements Supplier<GatewayTargetJson> { 293 294 @Override 295 public GatewayTargetJson get() { 296 GatewayTargetRetryStrategyJson gatewayTargetRetryStrategyJson = new GatewayTargetRetryStrategyJson(); 297 gatewayTargetRetryStrategyJson.setBackoffStrategy(RetryStrategyEnum.EXPONENTIAL); 298 gatewayTargetRetryStrategyJson.setBackoffInterval(100); 299 gatewayTargetRetryStrategyJson.setMaxRetries(2); 300 gatewayTargetRetryStrategyJson.setErrorRetryClasses( 301 Collections.singletonList("ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException")); 302 303 GatewayTargetJson targetJson = new GatewayTargetJson(); 304 targetJson.setRetryStrategy(gatewayTargetRetryStrategyJson); 305 targetJson.setBaseUrl("http://localhost:8000").setId("target1").setAllowedToFail(true); 306 targetJson.setHeadersToForward(Arrays.asList("Sample-Header-1", "Sample-Header-2")); 307 308 return targetJson; 309 } 310 } 311}