From 121629e41bc99b10b395e53c3e8cbb3a873a9115 Mon Sep 17 00:00:00 2001 From: Udara Pathum <46132469+hwupathum@users.noreply.github.com> Date: Wed, 3 Jul 2024 13:34:37 +0530 Subject: [PATCH] Add Httpclient5 as an OSGI service --- core/org.wso2.carbon.http.client/pom.xml | 111 ++++++++++++++++++ .../wso2/carbon/http/client/ClientUtils.java | 41 +++++++ .../http/client/HttpClientConstants.java | 31 +++++ .../http/client/cache/ClientBaseCache.java | 73 ++++++++++++ .../http/client/cache/HttpClientCache.java | 61 ++++++++++ .../client/exception/HttpClientException.java | 51 ++++++++ .../handler/AbstractResponseHandler.java | 23 ++++ .../client/handler/JsonResponseHandler.java | 50 ++++++++ .../internal/HttpClientServiceComponent.java | 34 ++++++ .../http/client/request/HttpPostRequest.java | 39 ++++++ .../client/services/HttpClientService.java | 36 ++++++ .../services/HttpClientServiceImpl.java | 54 +++++++++ .../src/main/resources/testing.xml | 28 +++++ .../client/cache/HttpClientCacheTest.java | 49 ++++++++ core/pom.xml | 1 + .../pom.xml | 2 + .../pom.xml | 2 + parent/pom.xml | 12 ++ 18 files changed, 698 insertions(+) create mode 100644 core/org.wso2.carbon.http.client/pom.xml create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/ClientUtils.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/HttpClientConstants.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/ClientBaseCache.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/HttpClientCache.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/exception/HttpClientException.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/AbstractResponseHandler.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/JsonResponseHandler.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/internal/HttpClientServiceComponent.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/request/HttpPostRequest.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientService.java create mode 100644 core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientServiceImpl.java create mode 100644 core/org.wso2.carbon.http.client/src/main/resources/testing.xml create mode 100644 core/org.wso2.carbon.http.client/src/test/java/org/wso2/carbon/http/client/cache/HttpClientCacheTest.java diff --git a/core/org.wso2.carbon.http.client/pom.xml b/core/org.wso2.carbon.http.client/pom.xml new file mode 100644 index 00000000000..b3cd3dea4d5 --- /dev/null +++ b/core/org.wso2.carbon.http.client/pom.xml @@ -0,0 +1,111 @@ + + + + + + + org.wso2.carbon + carbon-kernel + 4.10.17-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.http.client + bundle + WSO2 Carbon - Http Client + OSGi Bundle for Carbon Http Client + http://wso2.org + + + + org.osgi + org.osgi.service.component.annotations + + + org.osgi + org.osgi.annotation + + + org.osgi + org.osgi.service.metatype.annotations + + + org.osgi + org.osgi.compendium + provided + + + org.wso2.org.ops4j.pax.logging + pax-logging-api + + + org.wso2.orbit.org.apache.httpcomponents + httpclient5 + + + com.google.guava + guava + + + com.google.code.gson + gson + + + + org.wso2.orbit.org.apache.httpcomponents + httpcore5 + test + + + org.testng + testng + test + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + ${project.artifactId}-${project.version} + + org.wso2.carbon.http.client.internal, + + + org.osgi.framework.*, + org.apache.commons.logging.*; version="${import.package.version.commons.logging}", + org.wso2.carbon.caching.impl.*, + *;resolution:=optional + + + !org.wso2.carbon.http.client.internal, + org.wso2.carbon.http.client.*, + + + + + + + + diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/ClientUtils.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/ClientUtils.java new file mode 100644 index 00000000000..588546a0c05 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/ClientUtils.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.http.client; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; + +public class ClientUtils { + + private static final Log log = LogFactory.getLog(ClientUtils.class); + + private ClientUtils() { + } + + public static CloseableHttpClient createClient() { + + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().useSystemProperties(); + if (log.isDebugEnabled()) { + log.debug("Creating a new HttpClient instance"); + } + return httpClientBuilder.build(); + + } +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/HttpClientConstants.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/HttpClientConstants.java new file mode 100644 index 00000000000..75b56217028 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/HttpClientConstants.java @@ -0,0 +1,31 @@ +package org.wso2.carbon.http.client; + +public class HttpClientConstants { + + public enum Error { + + RESPONSE_ENTITY_EMPTY("12001", "Response entity is empty"), + RESPONSE_PARSE_ERROR("12002", "Error occurred while parsing the response"); + + private final String code; + private final String message; + private static final String API_ERROR_CODE_PREFIX = "HTC-"; + + Error(String code, String message) { + + this.code = code; + this.message = message; + } + + public String getCode() { + + return API_ERROR_CODE_PREFIX + code; + } + + public String getMessage() { + + return message; + } + } + +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/ClientBaseCache.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/ClientBaseCache.java new file mode 100644 index 00000000000..896cafc064b --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/ClientBaseCache.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.http.client.cache; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalListener; + +import java.io.Serializable; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +/** + * A base class for all cache implementations in Identity modules. This maintains caches in the tenanted space. + * A copy of this class is maintained at org.wso2.carbon.identity.organization.management.service.cache component. + * + * @param cache key type. + * @param cache value type. + */ +public abstract class ClientBaseCache { + + private final Cache cache; + + protected ClientBaseCache(int cacheSize, int expireAfterAccess, RemovalListener removalListener) { + + cache = CacheBuilder.newBuilder() + .maximumSize(cacheSize) + .expireAfterAccess(expireAfterAccess, TimeUnit.MILLISECONDS) + .removalListener(removalListener) + .build(); + } + + public void put(K key, V value) { + + cache.put(key, value); + } + + public V get(K key, Callable loader) { + + try { + return cache.get(key, loader); + } catch (ExecutionException e) { + // TODO: handle exception + return null; + } + } + + public V get(K key) { + + return cache.getIfPresent(key); + } + + public void cleanUp() { + + cache.cleanUp(); + } +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/HttpClientCache.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/HttpClientCache.java new file mode 100644 index 00000000000..60446b4e771 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/cache/HttpClientCache.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.http.client.cache; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; + +import java.io.IOException; + +public class HttpClientCache extends ClientBaseCache { + + private static final Log log = LogFactory.getLog(HttpClientCache.class); + private static HttpClientCache instance; + + + protected HttpClientCache(int cacheSize, int expireAfterAccess) { + + super(cacheSize, expireAfterAccess, httpClientCacheEntry -> { + // This is not called at expire + // https://stackoverflow.com/questions/21986551/guava-cachebuilder-doesnt-call-removal-listener + try { + if (httpClientCacheEntry.getValue() != null) { + CloseableHttpClient client = httpClientCacheEntry.getValue(); + client.close(); + if (log.isDebugEnabled()) { + log.debug("Http Client - " + httpClientCacheEntry.getKey() + " removed due to " + + httpClientCacheEntry.getCause()); + } + } + } catch (IOException e) { + log.error("Error occurred while closing the http client for key: " + httpClientCacheEntry.getKey(), e); + } + }); + } + + public static HttpClientCache getInstance() { + + if (instance == null) { + int ttlMinutes = 1; + int cacheTimeoutMinutes = 5; + instance = new HttpClientCache(100, (ttlMinutes + cacheTimeoutMinutes) * 60 * 1000); + } + return instance; + } +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/exception/HttpClientException.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/exception/HttpClientException.java new file mode 100644 index 00000000000..311972cf5aa --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/exception/HttpClientException.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.http.client.exception; + +import java.io.IOException; + +public class HttpClientException extends IOException { + + private String errorCode; + + public HttpClientException(String message) { + super(message); + } + + public HttpClientException(String errorCode, String message) { + + super(message); + this.errorCode = errorCode; + } + + public HttpClientException(String message, Throwable cause) { + + super(message, cause); + } + + public HttpClientException(String errorCode, String message, Throwable cause) { + + super(message, cause); + this.errorCode = errorCode; + } + + public String getErrorCode() { + + return errorCode; + } +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/AbstractResponseHandler.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/AbstractResponseHandler.java new file mode 100644 index 00000000000..04fd726ce9e --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/AbstractResponseHandler.java @@ -0,0 +1,23 @@ +package org.wso2.carbon.http.client.handler; + +import org.apache.hc.core5.http.ClassicHttpResponse; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.io.HttpClientResponseHandler; +import org.wso2.carbon.http.client.HttpClientConstants; +import org.wso2.carbon.http.client.exception.HttpClientException; + +public abstract class AbstractResponseHandler implements HttpClientResponseHandler { + + public T handleResponse(ClassicHttpResponse response) throws HttpClientException { + + // TODO: handle response status codes + HttpEntity entity = response.getEntity(); + if (entity == null) { + throw new HttpClientException(HttpClientConstants.Error.RESPONSE_ENTITY_EMPTY.getCode(), + HttpClientConstants.Error.RESPONSE_ENTITY_EMPTY.getMessage()); + } + return this.handleEntity(entity); + } + + protected abstract T handleEntity(HttpEntity httpEntity) throws HttpClientException; +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/JsonResponseHandler.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/JsonResponseHandler.java new file mode 100644 index 00000000000..8a22583094e --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/handler/JsonResponseHandler.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.http.client.handler; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.apache.hc.core5.http.ClassicHttpResponse; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.io.HttpClientResponseHandler; +import org.wso2.carbon.http.client.HttpClientConstants; +import org.wso2.carbon.http.client.exception.HttpClientException; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public class JsonResponseHandler extends AbstractResponseHandler { + + protected JsonObject handleEntity(HttpEntity entity) throws HttpClientException { + + try (final InputStream inputStream = entity.getContent()) { + if (inputStream == null) { + return null; + } + JsonElement jsonElement = + JsonParser.parseReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + return jsonElement.getAsJsonObject(); + } catch (IOException e) { + throw new HttpClientException(HttpClientConstants.Error.RESPONSE_PARSE_ERROR.getCode(), + HttpClientConstants.Error.RESPONSE_PARSE_ERROR.getMessage(), e); + } + } +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/internal/HttpClientServiceComponent.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/internal/HttpClientServiceComponent.java new file mode 100644 index 00000000000..34f8f889225 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/internal/HttpClientServiceComponent.java @@ -0,0 +1,34 @@ +package org.wso2.carbon.http.client.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.wso2.carbon.http.client.services.HttpClientService; +import org.wso2.carbon.http.client.services.HttpClientServiceImpl; + +@Component( + name = "http.client.component", + immediate = true +) +public class HttpClientServiceComponent { + + private static final Log LOGGER = LogFactory.getLog(HttpClientServiceComponent.class); + + @Activate + protected void activate(ComponentContext context) { + context.getBundleContext().registerService(HttpClientService.class, + new HttpClientServiceImpl(), null); + LOGGER.info("HttpClient bundle is activated"); + } + + @Deactivate + protected void deactivate(ComponentContext context) { + + LOGGER.debug("HttpClient service component deactivated"); + } + + +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/request/HttpPostRequest.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/request/HttpPostRequest.java new file mode 100644 index 00000000000..0d2fc0640e3 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/request/HttpPostRequest.java @@ -0,0 +1,39 @@ +package org.wso2.carbon.http.client.request; + +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.http.message.BasicNameValuePair; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class HttpPostRequest { + + private HttpPostRequest() { + } + + public static HttpPost createUrlEncodedRequest(String url, Map paramsMap) { + + HttpPost httpPost = new HttpPost(url); + List params = new ArrayList<>(); + for (Map.Entry entry : paramsMap.entrySet()) { + params.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); + } + httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8)); + + return httpPost; + } + + public static HttpPost createJsonRequest(String url, String jsonPayload) { + + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(new StringEntity(jsonPayload, ContentType.APPLICATION_JSON)); + + return httpPost; + } + +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientService.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientService.java new file mode 100644 index 00000000000..dcf49c69e31 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientService.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.http.client.services; + +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; + +import java.io.IOException; +import java.net.URL; +import java.util.concurrent.Callable; + +import javax.net.ssl.HttpsURLConnection; + +public interface HttpClientService { + + CloseableHttpClient getClosableHttpClient(String key, Callable loader); + + CloseableHttpClient getClosableHttpClient(String key); + + HttpsURLConnection getHttpsURLConnection(URL url, String httpMethod) + throws IOException; +} diff --git a/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientServiceImpl.java b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientServiceImpl.java new file mode 100644 index 00000000000..9725de85ea3 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/java/org/wso2/carbon/http/client/services/HttpClientServiceImpl.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.http.client.services; + +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.wso2.carbon.http.client.ClientUtils; +import org.wso2.carbon.http.client.cache.HttpClientCache; + +import java.io.IOException; +import java.net.URL; +import java.util.concurrent.Callable; + +import javax.net.ssl.HttpsURLConnection; + +public class HttpClientServiceImpl implements HttpClientService { + + @Override + public CloseableHttpClient getClosableHttpClient(String key, Callable loader) { + + return HttpClientCache.getInstance().get(key, loader); + } + + @Override + public CloseableHttpClient getClosableHttpClient(String key) { + + return HttpClientCache.getInstance().get(key, ClientUtils::createClient); + } + + @Override + public HttpsURLConnection getHttpsURLConnection(URL url, String httpMethod) + throws IOException { + + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setRequestMethod(httpMethod); + return connection; + } +} diff --git a/core/org.wso2.carbon.http.client/src/main/resources/testing.xml b/core/org.wso2.carbon.http.client/src/main/resources/testing.xml new file mode 100644 index 00000000000..c37030f0439 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/main/resources/testing.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/core/org.wso2.carbon.http.client/src/test/java/org/wso2/carbon/http/client/cache/HttpClientCacheTest.java b/core/org.wso2.carbon.http.client/src/test/java/org/wso2/carbon/http/client/cache/HttpClientCacheTest.java new file mode 100644 index 00000000000..d0c03add046 --- /dev/null +++ b/core/org.wso2.carbon.http.client/src/test/java/org/wso2/carbon/http/client/cache/HttpClientCacheTest.java @@ -0,0 +1,49 @@ +package org.wso2.carbon.http.client.cache; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.wso2.carbon.http.client.ClientUtils; + +public class HttpClientCacheTest { + + private static final int ACCESS_TIMEOUT = 1000; + + @Test(description = " Test case for cache put and get") + public void cachePutAndGetTest() { + HttpClientCache cache = new HttpClientCache(5, ACCESS_TIMEOUT); + + cache.put("key", ClientUtils.createClient()); + Assert.assertNotNull(cache.get("key")); + } + + @Test(description = " Test case for cache put and get with loader") + public void cachePutAndGetWithLoaderTest() { + HttpClientCache cache = new HttpClientCache(5, ACCESS_TIMEOUT); + + Assert.assertNotNull(cache.get("key", ClientUtils::createClient)); + } + + @Test(description = " Test case for cache eviction") + public void cacheEvictionTest() throws InterruptedException { + HttpClientCache cache = new HttpClientCache(5, ACCESS_TIMEOUT); + + cache.put("key", ClientUtils.createClient()); + Thread.sleep(ACCESS_TIMEOUT / 2); + Assert.assertNotNull(cache.get("key")); + Thread.sleep(ACCESS_TIMEOUT * 5); +// cache.cleanUp(); + Assert.assertNull(cache.get("key")); //return null + } + + @Test(description = " Test case for cache eviction with loader") + public void cacheEvictionLoaderTest() throws InterruptedException { + HttpClientCache cache = new HttpClientCache(5, ACCESS_TIMEOUT); + + cache.put("key", ClientUtils.createClient()); + Thread.sleep(ACCESS_TIMEOUT / 2); + Assert.assertNotNull(cache.get("key")); + Thread.sleep(ACCESS_TIMEOUT * 5); + Assert.assertNotNull(cache.get("key", ClientUtils::createClient)); //return null + } + +} diff --git a/core/pom.xml b/core/pom.xml index 3e55a543b6a..0ab3bc312a4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -122,6 +122,7 @@ org.wso2.carbon.application.deployer org.wso2.carbon.core org.wso2.carbon.bridge + org.wso2.carbon.http.client org.wso2.carbon.http.bridge org.wso2.carbon.servletbridge org.wso2.carbon.core.common diff --git a/features/org.wso2.carbon.core.common.feature/pom.xml b/features/org.wso2.carbon.core.common.feature/pom.xml index 5903b88b0e8..3debc01e964 100644 --- a/features/org.wso2.carbon.core.common.feature/pom.xml +++ b/features/org.wso2.carbon.core.common.feature/pom.xml @@ -100,6 +100,8 @@ org.wso2.orbit.commons-collections:commons-collections:${orbit.version.commons.collection} org.apache.httpcomponents.wso2:httpcore:${orbit.version.httpcore} + org.wso2.orbit.org.apache.httpcomponents:httpcore5:${orbit.version.httpcore5} + org.wso2.orbit.org.apache.httpcomponents:httpclient5:${orbit.version.httpclient5} org.compass-project.wso2:compass:${version.compass} commons-lang.wso2:commons-lang:${orbit.version.commons.lang} org.wso2.orbit.org.apache.poi:poi:${orbit.version.poi} diff --git a/features/org.wso2.carbon.core.server.feature/pom.xml b/features/org.wso2.carbon.core.server.feature/pom.xml index ab60be8ce35..a966a89cbd9 100644 --- a/features/org.wso2.carbon.core.server.feature/pom.xml +++ b/features/org.wso2.carbon.core.server.feature/pom.xml @@ -67,6 +67,8 @@ org.wso2.carbon:org.wso2.carbon.admin.advisory.mgt:${carbon.kernel.version} + org.wso2.carbon:org.wso2.carbon.http.client:${carbon.kernel.version} + org.wso2.orbit.org.bouncycastle:bcprov-jdk18on:${bouncycastle.version} org.wso2.orbit.org.bouncycastle:bcpkix-jdk18on:${bouncycastle.version} diff --git a/parent/pom.xml b/parent/pom.xml index fd02488607f..2c628d1e20f 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -547,6 +547,8 @@ 1.8.wso2v1 4.4.14.wso2v1 + 5.2.1.wso2v1 + 5.2.1.wso2v1 1.6.2.wso2v4 3.1.0.wso2v6 1.5.6.wso2v1 @@ -1176,6 +1178,16 @@ httpcore ${orbit.version.httpcore} + + org.wso2.orbit.org.apache.httpcomponents + httpcore5 + ${orbit.version.httpcore5} + + + org.wso2.orbit.org.apache.httpcomponents + httpclient5 + ${orbit.version.httpclient5} + net.sf.ehcache.wso2 ehcache