diff --git a/felles/klient/src/main/java/no/nav/vedtak/klient/http/BaseHttpClient.java b/felles/klient/src/main/java/no/nav/vedtak/klient/http/BaseHttpClient.java new file mode 100644 index 000000000..1013cd4b9 --- /dev/null +++ b/felles/klient/src/main/java/no/nav/vedtak/klient/http/BaseHttpClient.java @@ -0,0 +1,111 @@ +package no.nav.vedtak.klient.http; + +import no.nav.vedtak.exception.IntegrasjonException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Set; + +public class BaseHttpClient { + + private static final Logger LOG = LoggerFactory.getLogger(BaseHttpClient.class); + private static final int RETRIES = 2; // 1 attempt, the n retries + + private final HttpClient httpClient; + + protected BaseHttpClient(HttpClient httpClient) { + this.httpClient = httpClient; + } + + public String send(HttpClientRequest request) { + var httpRequest = request.request(); + return ResponseHandler.handleResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), Set.of()); + } + + public String send(HttpClientRequest request, Set acceptStatus) { + var httpRequest = request.request(); + return ResponseHandler.handleResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), acceptStatus); + } + + public byte[] sendReturnByteArray(HttpClientRequest request) { + var httpRequest = request.request(); + return ResponseHandler.handleResponse(doSendExpectBytearrayRetry(httpRequest), httpRequest.uri(), Set.of()); + } + + public HttpResponse sendReturnResponse(HttpClientRequest request) { + var httpRequest = request.request(); + return ResponseHandler.handleRawResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), Set.of()); + } + + public HttpResponse sendReturnResponse(HttpClientRequest request, Set acceptStatus) { + var httpRequest = request.request(); + return ResponseHandler.handleRawResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), acceptStatus); + } + + public HttpResponse sendReturnResponseByteArray(HttpClientRequest request) { + var httpRequest = request.request(); + return ResponseHandler.handleRawResponse(doSendExpectBytearrayRetry(httpRequest), httpRequest.uri(), Set.of()); + } + + /** + * Raw response, not checked for status codes 4nn or 5nn - please ensure that any usage avoids "quiet errors" + */ + public HttpResponse sendReturnUnhandled(HttpClientRequest request) { + return doSendExpectStringRetry(request.request()); + } + + public HttpResponse sendReturnUnhandledNoRetry(HttpClientRequest request) { + return doSendExpectString(request.request()); + } + + private HttpResponse doSendExpectBytearrayRetry(HttpRequest httpRequest) { + int i = RETRIES; + while (i-- > 0) { + try { + return doSendExpectBytearray(httpRequest); + } catch (IntegrasjonException e) { + LOG.trace("F-157390 IntegrasjonException ved kall {} til endepunkt {}", RETRIES - i, e); + } + } + return doSendExpectBytearray(httpRequest); + } + + private HttpResponse doSendExpectStringRetry(HttpRequest httpRequest) { + int i = RETRIES; + while (i-- > 0) { + try { + return doSendExpectString(httpRequest); + } catch (IntegrasjonException e) { + LOG.trace("F-157390 IntegrasjonException ved kall {} til endepunkt {}", RETRIES - i, e); + } + } + return doSendExpectString(httpRequest); + } + + private HttpResponse doSendExpectBytearray(HttpRequest request) { + try { + return httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray()); + } catch (IOException e) { + throw new IntegrasjonException("F-157391", "Uventet IO-exception mot endepunkt", e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IntegrasjonException("F-157392", "InterruptedException ved kall mot endepunkt", e); + } + } + + private HttpResponse doSendExpectString(HttpRequest request) { + try { + return httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + } catch (IOException e) { + throw new IntegrasjonException("F-157391", "Uventet IO-exception mot endepunkt", e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IntegrasjonException("F-157392", "InterruptedException ved kall mot endepunkt", e); + } + } +} diff --git a/felles/klient/src/main/java/no/nav/vedtak/klient/http/DefaultHttpClient.java b/felles/klient/src/main/java/no/nav/vedtak/klient/http/DefaultHttpClient.java index 411645197..f397b125e 100644 --- a/felles/klient/src/main/java/no/nav/vedtak/klient/http/DefaultHttpClient.java +++ b/felles/klient/src/main/java/no/nav/vedtak/klient/http/DefaultHttpClient.java @@ -1,16 +1,7 @@ package no.nav.vedtak.klient.http; -import java.io.IOException; import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; import java.time.Duration; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import no.nav.vedtak.exception.IntegrasjonException; /** * Generic interface to using java.net.http.HttpClient using HttpKlientRequest to ensure callId and timeout @@ -20,17 +11,12 @@ * - Create a HttpRequest.Builder with URI, Method, and custom headers. * - Use DefaultHttpKlient.instance().sendAccept(HttpKlientRequest.callId(builder)) */ -public final class DefaultHttpClient { - - private static final Logger LOG = LoggerFactory.getLogger(DefaultHttpClient.class); - private static final int RETRIES = 2; // 1 attempt, the n retries +public final class DefaultHttpClient extends BaseHttpClient { private static DefaultHttpClient CLIENT; - private final HttpClient httpClient; - private DefaultHttpClient() { - this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(15)).proxy(HttpClient.Builder.NO_PROXY).build(); + super(HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(15)).proxy(HttpClient.Builder.NO_PROXY).build()); } public static synchronized DefaultHttpClient client() { @@ -41,94 +27,5 @@ public static synchronized DefaultHttpClient client() { } return inst; } - - public String send(HttpClientRequest request) { - var httpRequest = request.request(); - return ResponseHandler.handleResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), Set.of()); - } - - public String send(HttpClientRequest request, Set acceptStatus) { - var httpRequest = request.request(); - return ResponseHandler.handleResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), acceptStatus); - } - - public byte[] sendReturnByteArray(HttpClientRequest request) { - var httpRequest = request.request(); - return ResponseHandler.handleResponse(doSendExpectBytearrayRetry(httpRequest), httpRequest.uri(), Set.of()); - } - - public HttpResponse sendReturnResponse(HttpClientRequest request) { - var httpRequest = request.request(); - return ResponseHandler.handleRawResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), Set.of()); - } - - public HttpResponse sendReturnResponse(HttpClientRequest request, Set acceptStatus) { - var httpRequest = request.request(); - return ResponseHandler.handleRawResponse(doSendExpectStringRetry(httpRequest), httpRequest.uri(), acceptStatus); - } - - public HttpResponse sendReturnResponseByteArray(HttpClientRequest request) { - var httpRequest = request.request(); - return ResponseHandler.handleRawResponse(doSendExpectBytearrayRetry(httpRequest), httpRequest.uri(), Set.of()); - } - - /** - * Raw response, not checked for status codes 4nn or 5nn - please ensure that any usage avoids "quiet errors" - */ - public HttpResponse sendReturnUnhandled(HttpClientRequest request) { - return doSendExpectStringRetry(request.request()); - } - - public HttpResponse sendReturnUnhandledNoRetry(HttpClientRequest request) { - return doSendExpectString(request.request()); - } - - private HttpResponse doSendExpectBytearrayRetry(HttpRequest httpRequest) { - int i = RETRIES; - while (i-- > 0) { - try { - return doSendExpectBytearray(httpRequest); - } catch (IntegrasjonException e) { - LOG.trace("F-157390 IntegrasjonException ved kall {} til endepunkt {}", RETRIES - i, e); - } - } - return doSendExpectBytearray(httpRequest); - } - - private HttpResponse doSendExpectStringRetry(HttpRequest httpRequest) { - int i = RETRIES; - while (i-- > 0) { - try { - return doSendExpectString(httpRequest); - } catch (IntegrasjonException e) { - LOG.trace("F-157390 IntegrasjonException ved kall {} til endepunkt {}", RETRIES - i, e); - } - } - return doSendExpectString(httpRequest); - } - - private HttpResponse doSendExpectBytearray(HttpRequest request) { - try { - return httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray()); - } catch (IOException e) { - throw new IntegrasjonException("F-157391", "Uventet IO-exception mot endepunkt", e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IntegrasjonException("F-157392", "InterruptedException ved kall mot endepunkt", e); - } - } - - private HttpResponse doSendExpectString(HttpRequest request) { - try { - return httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - } catch (IOException e) { - throw new IntegrasjonException("F-157391", "Uventet IO-exception mot endepunkt", e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IntegrasjonException("F-157392", "InterruptedException ved kall mot endepunkt", e); - } - } - - } diff --git a/felles/klient/src/main/java/no/nav/vedtak/klient/http/ProxyHttpClient.java b/felles/klient/src/main/java/no/nav/vedtak/klient/http/ProxyHttpClient.java new file mode 100644 index 000000000..fdf5cf97a --- /dev/null +++ b/felles/klient/src/main/java/no/nav/vedtak/klient/http/ProxyHttpClient.java @@ -0,0 +1,42 @@ +package no.nav.vedtak.klient.http; + +import no.nav.foreldrepenger.konfig.Environment; + +import java.net.InetSocketAddress; +import java.net.ProxySelector; +import java.net.URI; +import java.net.http.HttpClient; +import java.time.Duration; +import java.util.Optional; + +public final class ProxyHttpClient extends BaseHttpClient { + private static final Environment ENV = Environment.current(); + + private static final String AZURE_HTTP_PROXY = "azure.http.proxy"; + private static final String PROXY_KEY = "proxy.url"; + private static final String DEFAULT_PROXY_URL = "http://webproxy.nais:8088"; + + private static ProxyHttpClient CLIENT; + + private ProxyHttpClient() { + super(HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(15)) + .proxy(Optional.ofNullable(ENV.isFss() ? URI.create(ENV.getProperty(AZURE_HTTP_PROXY, getDefaultProxy())) : null) + .map(p -> new InetSocketAddress(p.getHost(), p.getPort())) + .map(ProxySelector::of) + .orElse(HttpClient.Builder.NO_PROXY)).build()); + } + + public static synchronized ProxyHttpClient client() { + var inst = CLIENT; + if (inst == null) { + inst = new ProxyHttpClient(); + CLIENT = inst; + } + return inst; + } + + private static String getDefaultProxy() { + return ENV.getProperty(PROXY_KEY, DEFAULT_PROXY_URL); + } +} diff --git a/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/BaseRestClient.java b/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/BaseRestClient.java new file mode 100644 index 000000000..ca6846d30 --- /dev/null +++ b/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/BaseRestClient.java @@ -0,0 +1,79 @@ +package no.nav.vedtak.felles.integrasjon.rest; + +import no.nav.vedtak.klient.http.BaseHttpClient; +import no.nav.vedtak.mapper.json.DefaultJsonMapper; + +import java.net.HttpURLConnection; +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; + +class BaseRestClient { + + private BaseHttpClient httpklient; + + public BaseRestClient(BaseHttpClient httpClient) { + this.httpklient = httpClient; + } + + public T send(RestRequest request, Class clazz) { + var response = httpklient.send(request); + return mapResponse(response, s -> false, clazz); + } + + public T sendExpectConflict(RestRequest request, Class clazz) { + var response = httpklient.send(request, Set.of(HttpURLConnection.HTTP_CONFLICT)); + return mapResponse(response, s -> false, clazz); + } + + public Optional sendReturnOptional(RestRequest request, Class clazz) { + var response = httpklient.send(request); + return Optional.ofNullable(mapResponse(response, String::isEmpty, clazz)); + } + + public List sendReturnList(RestRequest request, Class clazz) { + var response = httpklient.send(request); + return DefaultJsonMapper.listFromJson(response, clazz); + } + + public Map sendReturnMap(RestRequest request, Class clazz) { + var response = httpklient.send(request); + return DefaultJsonMapper.mapFromJson(response, clazz); + } + + public byte[] sendReturnByteArray(RestRequest request) { + return httpklient.sendReturnByteArray(request); + } + + public HttpResponse sendReturnResponseString(RestRequest request) { + return httpklient.sendReturnResponse(request); + } + + public HttpResponse sendReturnResponseByteArray(RestRequest request) { + return httpklient.sendReturnResponseByteArray(request); + } + + /** + * Raw response, not checked for status codes 4nn or 5nn - please ensure that any usage avoids "quiet errors" + */ + public HttpResponse sendReturnUnhandled(RestRequest request) { + return httpklient.sendReturnUnhandled(request); + } + + public HttpResponse sendReturnUnhandledNoRetry(RestRequest request) { + return httpklient.sendReturnUnhandledNoRetry(request); + } + + private T mapResponse(String response, Predicate filterOut, Class clazz) { + if (response == null || filterOut.test(response)) { + return null; + } + if (clazz.isAssignableFrom(String.class)) { + return clazz.cast(response); + } + return DefaultJsonMapper.fromJson(response, clazz); + } +} diff --git a/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/ProxyRestClient.java b/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/ProxyRestClient.java new file mode 100644 index 000000000..8025d2f9e --- /dev/null +++ b/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/ProxyRestClient.java @@ -0,0 +1,15 @@ +package no.nav.vedtak.felles.integrasjon.rest; + +import no.nav.vedtak.klient.http.ProxyHttpClient; + +public final class ProxyRestClient extends BaseRestClient { + + private ProxyRestClient() { + super(ProxyHttpClient.client()); + } + + public static ProxyRestClient client() { + return new ProxyRestClient(); + } + +} diff --git a/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/RestClient.java b/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/RestClient.java index aa06f5a77..5e201fb5d 100644 --- a/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/RestClient.java +++ b/integrasjon/rest-klient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/RestClient.java @@ -1,83 +1,14 @@ package no.nav.vedtak.felles.integrasjon.rest; -import java.net.HttpURLConnection; -import java.net.http.HttpResponse; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Predicate; - import no.nav.vedtak.klient.http.DefaultHttpClient; -import no.nav.vedtak.mapper.json.DefaultJsonMapper; - -public final class RestClient { - private final DefaultHttpClient httpklient; +public final class RestClient extends BaseRestClient { private RestClient() { - this.httpklient = DefaultHttpClient.client(); + super(DefaultHttpClient.client()); } public static RestClient client() { return new RestClient(); } - - public T send(RestRequest request, Class clazz) { - var response = httpklient.send(request); - return mapResponse(response, s -> false, clazz); - } - - public T sendExpectConflict(RestRequest request, Class clazz) { - var response = httpklient.send(request, Set.of(HttpURLConnection.HTTP_CONFLICT)); - return mapResponse(response, s -> false, clazz); - } - - public Optional sendReturnOptional(RestRequest request, Class clazz) { - var response = httpklient.send(request); - return Optional.ofNullable(mapResponse(response, String::isEmpty, clazz)); - } - - public List sendReturnList(RestRequest request, Class clazz) { - var response = httpklient.send(request); - return DefaultJsonMapper.listFromJson(response, clazz); - } - - public Map sendReturnMap(RestRequest request, Class clazz) { - var response = httpklient.send(request); - return DefaultJsonMapper.mapFromJson(response, clazz); - } - - public byte[] sendReturnByteArray(RestRequest request) { - return httpklient.sendReturnByteArray(request); - } - - public HttpResponse sendReturnResponseString(RestRequest request) { - return httpklient.sendReturnResponse(request); - } - - public HttpResponse sendReturnResponseByteArray(RestRequest request) { - return httpklient.sendReturnResponseByteArray(request); - } - - /** - * Raw response, not checked for status codes 4nn or 5nn - please ensure that any usage avoids "quiet errors" - */ - public HttpResponse sendReturnUnhandled(RestRequest request) { - return httpklient.sendReturnUnhandled(request); - } - - public HttpResponse sendReturnUnhandledNoRetry(RestRequest request) { - return httpklient.sendReturnUnhandledNoRetry(request); - } - - private T mapResponse(String response, Predicate filterOut, Class clazz) { - if (response == null || filterOut.test(response)) { - return null; - } - if (clazz.isAssignableFrom(String.class)) { - return clazz.cast(response); - } - return DefaultJsonMapper.fromJson(response, clazz); - } }