Commit 0cf4d75a authored by Muskan Srivastava's avatar Muskan Srivastava
Browse files

added httpClientAzure, EntitlementsFactoryAzure and RetryAndTimeoutsConfiguration

parent bacfce18
Pipeline #40642 failed with stage
in 38 seconds
......@@ -49,7 +49,7 @@
<reactor.version>Dysprosium-SR12</reactor.version>
<netty.version>4.1.51.Final</netty.version>
<lombok.version>1.18.16</lombok.version>
<osdu.oscorecommon.version>0.3.23</osdu.oscorecommon.version>
<osdu.oscorecommon.version>0.9.0-SNAPSHOT</osdu.oscorecommon.version>
<mockito-junit-jupiter.version>2.23.0</mockito-junit-jupiter.version>
<spring-boot-starter-log4j2.version>2.3.4.RELEASE</spring-boot-starter-log4j2.version>
<azure-mgmt-eventgrid.version>1.0.0-beta-3</azure-mgmt-eventgrid.version>
......@@ -216,6 +216,16 @@
<version>${azure.appinsights.log4j.version}</version>
</dependency>
<!-- resilience4j dependency--><dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-retry</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-core</artifactId>
<version>1.7.0</version>
</dependency>
<!-- Other dependencies -->
<dependency>
......
package org.opengroup.osdu.azure.retry;
import org.opengroup.osdu.core.common.entitlements.*;
import org.opengroup.osdu.core.common.http.IHttpClient;
import org.opengroup.osdu.core.common.http.json.HttpResponseBodyMapper;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.springframework.stereotype.Component;
public class EntitlementsFactoryAzure implements IEntitlementsFactory {
private final EntitlementsAPIConfig config;
private final HttpResponseBodyMapper mapper;
public EntitlementsFactoryAzure(EntitlementsAPIConfig config, HttpResponseBodyMapper mapper) {
this.config = config;
this.mapper = mapper;
}
@Override
public IEntitlementsService create(DpsHeaders headers) {
if (headers == null) {
throw new NullPointerException("headers cannot be null");
}
RetryAndTimeoutConfiguration config = new RetryAndTimeoutConfiguration();
config.setMaxRetryAttempts(10);
return new EntitlementsService(this.config,
new HttpClientAzure(config),
headers, mapper);
}
}
package org.opengroup.osdu.azure.retry;
import com.google.api.client.http.HttpMethods;
import io.github.resilience4j.retry.Retry;
import io.github.resilience4j.retry.RetryConfig;
import io.github.resilience4j.retry.RetryRegistry;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.opengroup.osdu.core.common.http.HttpRequest;
import org.opengroup.osdu.core.common.http.HttpResponse;
import org.opengroup.osdu.core.common.http.IHttpClient;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.model.http.RequestStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public class HttpClientAzure implements IHttpClient {
@Autowired
@Lazy
private JaxRsDpsLog log;
private final RequestConfig REQUEST_CONFIG = RequestConfig.custom()
.setConnectTimeout(60000)
.setConnectionRequestTimeout(60000)
.setSocketTimeout(60000).build();
private RetryConfig retryConfig;
public HttpClientAzure()
{
}
public HttpClientAzure(RetryAndTimeoutConfiguration retryAndTimeoutConfiguration)
{
this.retryConfig = retryAndTimeoutConfiguration.getRetryConfig();
}
@Override
public HttpResponse send(HttpRequest request) {
HttpResponse output = new HttpResponse();
output.setRequest(request);
Long curTimeStamp = System.currentTimeMillis();
HttpUriRequest req = null;
try {
req = getRequest(request);
} catch (URISyntaxException e) {
//TODO Better handling of exception
e.printStackTrace();
}
List<Header> httpHeaders = new ArrayList<>();
for (String key : request.getHeaders().keySet()) {
httpHeaders.add(new BasicHeader(key, request.getHeaders().get(key)));
}
if (!request.getHeaders().containsKey(HttpHeaders.ACCEPT)) {
httpHeaders.add(new BasicHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString()));
}
try {
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultHeaders(httpHeaders)
.setDefaultRequestConfig(REQUEST_CONFIG)
.build();
try (CloseableHttpResponse response = this.getHttpClientWithRetry(httpclient,req)) {
StringBuilder responseBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))) {
String responsePayloadLine;
while ((responsePayloadLine = br.readLine()) != null) {
responseBuilder.append(responsePayloadLine);
}
}
String responseBody = responseBuilder.toString();
// handle case where upstream server is running out of resources and throwing generic exception
// checkResponseMediaType(response, responseBody);
output.setResponseCode(response.getStatusLine().getStatusCode());
output.setBody(responseBody);
if (output.getResponseCode() != 200) {
log.info(String.format("method: %s | response code: %s | url: %s | error message: %s", req.getMethod(), output.getResponseCode(), req.getURI().toString(), responseBody));
}
return output;
}
} catch (SocketTimeoutException e) {
throw new AppException(RequestStatus.SOCKET_TIMEOUT, "Socket time out", "Request cannot be completed in specified time", e);
} catch (IOException e) {
throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal communication failure", "Internal communication failure", e);
} finally {
// Long latency = System.currentTimeMillis() - curTimeStamp;
// log.info(String.format("method: %s | latency: %s | url: %s | correlation id: %s", req.getMethod(), latency, req.getURI().toString(), request.getHeaders().get(DpsHeaders.CORRELATION_ID)));
}
}
private CloseableHttpResponse getHttpClientWithRetry(CloseableHttpClient httpClient, HttpUriRequest request)
{
RetryConfig config = this.retryConfig;
RetryRegistry registry = RetryRegistry.of(config);
Retry retry = registry.retry("retryPolicy", config);
Supplier<CloseableHttpResponse> httpClientSupplier = ()-> {
try {
return httpClient.execute(request);
} catch (IOException e) {
//TODO Better handling of exception
e.printStackTrace();
}
return null;
};
Supplier<CloseableHttpResponse> supplierWithRetry =Retry.decorateSupplier(retry,httpClientSupplier);
return supplierWithRetry.get();
}
private HttpUriRequest getRequest(HttpRequest request) throws URISyntaxException {
URIBuilder builder = new URIBuilder(request.getUrl());
Map<String, String> queryParams = request.getQueryParams();
if (queryParams != null && !queryParams.isEmpty()) {
for (String param : queryParams.keySet()) {
builder.setParameter(param, queryParams.get(param));
}
}
String body = request.getBody();
switch (request.getHttpMethod()) {
case HttpMethods.POST: {
HttpPost req = new HttpPost(builder.build());
req.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
return req;
}
case HttpMethods.GET: {
HttpGet req = new HttpGet(builder.build());
return req;
}
case HttpMethods.PUT: {
HttpPut req = new HttpPut(builder.build());
req.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
return req;
}
default:
throw new AppException(HttpStatus.SC_NOT_FOUND, "Invalid HTTP method", "Invalid HTTP method");
}
}
}
package org.opengroup.osdu.azure.retry;
import io.github.resilience4j.retry.RetryConfig;
import lombok.Data;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.opengroup.osdu.core.common.http.HttpResponse;
import java.time.Duration;
@Data
public class RetryAndTimeoutConfiguration {
private int maxRetryAttempts = 3;
private int waitDurationInMillis = 1000;
private boolean exponentialBackOff = false;
public RetryConfig getRetryConfig()
{
return RetryConfig.<CloseableHttpResponse>custom()
.maxAttempts(10)
.waitDuration(Duration.ofMillis(1000))
.retryOnResult(response -> isRetryRequired(response))
.build();
}
private boolean isRetryRequired(CloseableHttpResponse response)
{
if(response.getStatusLine().getStatusCode()==200 ||
response.getStatusLine().getStatusCode()==403 ||
response.getStatusLine().getStatusCode()==404 ||
response.getStatusLine().getStatusCode()==500)
// && retryConfigParameters.isRetryEnabled())
{
return true;
}
return false;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment