Pooling OAuth token validator stub initialization

merge-requests/7/head
prabathabey 9 years ago
parent 262e53ddcc
commit 11957f1e47

@ -118,6 +118,18 @@
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<log4j.configuration>file:src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
@ -182,6 +194,22 @@
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.wso2</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>commons-httpclient.wso2</groupId>
<artifactId>commons-httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
</dependency>
<dependency>
<groupId>commons-pool.wso2</groupId>
<artifactId>commons-pool</artifactId>
</dependency>
</dependencies>
</project>

@ -24,15 +24,14 @@ import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
import org.wso2.carbon.webapp.authenticator.framework.authenticator.oauth.OAuthConstants;
@ -46,19 +45,94 @@ public class OAuthTokenValidationStubFactory implements PoolableObjectFactory {
private String url;
private String basicAuthHeader;
private static final Log log = LogFactory.getLog(OAuthTokenValidationStubFactory.class);
private HttpClient httpClient;
private static final Log log = LogFactory.getLog(OAuthTokenValidationStubFactory.class);
public OAuthTokenValidationStubFactory(String url, String adminUsername, String adminPassword,
Properties properties) {
this.validateUrl(url);
this.url = url;
this.validateCredentials(adminUsername, adminPassword);
this.basicAuthHeader = new String(Base64.encodeBase64((adminUsername + ":" + adminPassword).getBytes()));
HttpConnectionManager connectionManager = this.createConnectionManager(properties);
this.httpClient = new HttpClient(connectionManager);
}
/**
* Creates an instance of MultiThreadedHttpConnectionManager using HttpClient 3.x APIs
*
* @param properties Properties to configure MultiThreadedHttpConnectionManager
* @return An instance of properly configured MultiThreadedHttpConnectionManager
*/
private HttpConnectionManager createConnectionManager(Properties properties) {
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
if (properties == null || properties.isEmpty()) {
throw new IllegalArgumentException("Parameters required to initialize HttpClient instances " +
"associated with OAuth token validation service stub are not provided");
}
String maxConnectionsPerHostParam = properties.getProperty("MaxConnectionsPerHost");
if (maxConnectionsPerHostParam == null || maxConnectionsPerHostParam.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("MaxConnectionsPerHost parameter is not explicitly defined. Therefore, the default, " +
"which is 2, will be used");
}
} else {
params.setDefaultMaxConnectionsPerHost(Integer.parseInt(maxConnectionsPerHostParam));
}
String maxTotalConnectionsParam = properties.getProperty("MaxTotalConnections");
if (maxTotalConnectionsParam == null || maxTotalConnectionsParam.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("MaxTotalConnections parameter is not explicitly defined. Therefore, the default, " +
"which is 10, will be used");
}
} else {
params.setMaxTotalConnections(Integer.parseInt(maxTotalConnectionsParam));
}
HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.setParams(params);
return connectionManager;
}
/**
* Creates an instance of PoolingHttpClientConnectionManager using HttpClient 4.x APIs
*
* @param properties Properties to configure PoolingHttpClientConnectionManager
* @return An instance of properly configured PoolingHttpClientConnectionManager
*/
private HttpClientConnectionManager createClientConnectionManager(Properties properties) {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(Integer.parseInt(properties.getProperty("MaxConnectionsPerHost")));
connectionManager.setMaxTotal(Integer.parseInt(properties.getProperty("MaxTotalConnections")));
this.httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
if (properties != null) {
String maxConnectionsPerHostParam = properties.getProperty("MaxConnectionsPerHost");
if (maxConnectionsPerHostParam == null || maxConnectionsPerHostParam.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("MaxConnectionsPerHost parameter is not explicitly defined. Therefore, the default, " +
"which is 2, will be used");
}
} else {
connectionManager.setDefaultMaxPerRoute(Integer.parseInt(maxConnectionsPerHostParam));
}
String maxTotalConnectionsParam = properties.getProperty("MaxTotalConnections");
if (maxTotalConnectionsParam == null || maxTotalConnectionsParam.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("MaxTotalConnections parameter is not explicitly defined. Therefore, the default, " +
"which is 10, will be used");
}
} else {
connectionManager.setMaxTotal(Integer.parseInt(maxTotalConnectionsParam));
}
} else {
if (log.isDebugEnabled()) {
log.debug("Properties, i.e. MaxTotalConnections/MaxConnectionsPerHost, required to tune the " +
"HttpClient used in OAuth token validation service stub instances are not provided. " +
"Therefore, the defaults, 2/10 respectively, will be used");
}
}
return connectionManager;
}
@Override
@ -88,7 +162,6 @@ public class OAuthTokenValidationStubFactory implements PoolableObjectFactory {
if (o instanceof OAuth2TokenValidationServiceStub) {
OAuth2TokenValidationServiceStub stub = (OAuth2TokenValidationServiceStub) o;
stub._getServiceClient().cleanupTransport();
stub._getServiceClient().setOptions(null);
}
}
@ -111,10 +184,28 @@ public class OAuthTokenValidationStubFactory implements PoolableObjectFactory {
options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, "true");
client.setOptions(options);
} catch (AxisFault axisFault) {
throw new OAuthTokenValidationException("Exception occurred while creating the " +
throw new OAuthTokenValidationException("Error occurred while creating the " +
"OAuth2TokenValidationServiceStub.", axisFault);
}
return stub;
}
private void validateUrl(String url) {
if (url == null || url.isEmpty()) {
throw new IllegalArgumentException("Url provided as the endpoint of the OAuth token validation service " +
"is null");
}
}
private void validateCredentials(String adminUsername, String adminPassword) {
if (adminUsername == null || adminUsername.isEmpty()) {
throw new IllegalArgumentException("An appropriate username required to initialize OAuth token " +
"validation service stub factory hasn't been provided");
}
if (adminPassword == null || adminPassword.isEmpty()) {
throw new IllegalArgumentException("An appropriate password required to initialize OAuth token " +
"validation service stub factory hasn't been provided");
}
}
}

@ -26,7 +26,8 @@ import java.util.Map;
public class WebappAuthenticatorFactory {
public static WebappAuthenticator getAuthenticator(String authScheme) {
return AuthenticatorFrameworkDataHolder.getInstance().getWebappAuthenticatorRepository().getAuthenticator(authScheme);
return AuthenticatorFrameworkDataHolder.getInstance().getWebappAuthenticatorRepository().
getAuthenticator(authScheme);
}
public static WebappAuthenticator getAuthenticator(Request request) {

@ -59,36 +59,21 @@ public class RemoteOAuthValidator implements OAuth2TokenValidator {
}
@Override
public OAuthValidationResponse validateToken(String accessToken, String resource) throws
OAuthTokenValidationException {
OAuth2TokenValidationRequestDTO validationRequest = new OAuth2TokenValidationRequestDTO();
OAuth2TokenValidationRequestDTO_OAuth2AccessToken oauthToken =
new OAuth2TokenValidationRequestDTO_OAuth2AccessToken();
oauthToken.setTokenType(OAuthConstants.BEARER_TOKEN_TYPE);
oauthToken.setIdentifier(accessToken);
validationRequest.setAccessToken(oauthToken);
//Set the resource context param. This will be used in scope validation.
OAuth2TokenValidationRequestDTO_TokenValidationContextParam resourceContextParam = new
OAuth2TokenValidationRequestDTO_TokenValidationContextParam();
resourceContextParam.setKey(OAuthConstants.RESOURCE_KEY);
resourceContextParam.setValue(resource);
OAuth2TokenValidationRequestDTO_TokenValidationContextParam[] tokenValidationContextParams =
new OAuth2TokenValidationRequestDTO_TokenValidationContextParam[1];
tokenValidationContextParams[0] = resourceContextParam;
validationRequest.setContext(tokenValidationContextParams);
OAuth2TokenValidationResponseDTO tokenValidationResponse;
public OAuthValidationResponse validateToken(String accessToken,
String resource) throws OAuthTokenValidationException {
OAuth2TokenValidationServiceStub stub = null;
OAuth2TokenValidationResponseDTO validationResponse;
try {
OAuth2TokenValidationRequestDTO validationRequest = this.createValidationRequest(accessToken, resource);
stub = (OAuth2TokenValidationServiceStub) stubs.borrowObject();
tokenValidationResponse = stub.
validationResponse = stub.
findOAuthConsumerIfTokenIsValid(validationRequest).getAccessTokenValidationResponse();
} catch (RemoteException e) {
throw new OAuthTokenValidationException("Remote Exception occurred while invoking the Remote " +
"IS server for OAuth2 token validation.", e);
} catch (Exception e) {
/* In this particular instance, generic exceptions are caught as enforced by the pooling library
used to pool stubs created to invoke OAuth token validation service */
throw new OAuthTokenValidationException("Error occurred while borrowing an oauth token validation " +
"service stub from the pool", e);
} finally {
@ -99,19 +84,49 @@ public class RemoteOAuthValidator implements OAuth2TokenValidator {
" stub pool", e);
}
}
boolean isValid = tokenValidationResponse.getValid();
if (validationResponse == null) {
if (log.isDebugEnabled()) {
log.debug("Response returned by the OAuth token validation service is null");
}
return null;
}
String userName;
String tenantDomain;
boolean isValid = validationResponse.getValid();
if (isValid) {
userName = MultitenantUtils.getTenantAwareUsername(
tokenValidationResponse.getAuthorizedUser());
tenantDomain = MultitenantUtils.getTenantDomain(tokenValidationResponse.getAuthorizedUser());
validationResponse.getAuthorizedUser());
tenantDomain = MultitenantUtils.getTenantDomain(validationResponse.getAuthorizedUser());
} else {
OAuthValidationResponse oAuthValidationResponse = new OAuthValidationResponse();
oAuthValidationResponse.setErrorMsg(tokenValidationResponse.getErrorMsg());
oAuthValidationResponse.setErrorMsg(validationResponse.getErrorMsg());
return oAuthValidationResponse;
}
return new OAuthValidationResponse(userName, tenantDomain, isValid);
}
private OAuth2TokenValidationRequestDTO createValidationRequest(String accessToken, String resource) {
OAuth2TokenValidationRequestDTO validationRequest = new OAuth2TokenValidationRequestDTO();
OAuth2TokenValidationRequestDTO_OAuth2AccessToken oauthToken =
new OAuth2TokenValidationRequestDTO_OAuth2AccessToken();
oauthToken.setTokenType(OAuthConstants.BEARER_TOKEN_TYPE);
oauthToken.setIdentifier(accessToken);
validationRequest.setAccessToken(oauthToken);
//Set the resource context param. This will be used in scope validation.
OAuth2TokenValidationRequestDTO_TokenValidationContextParam resourceContextParam = new
OAuth2TokenValidationRequestDTO_TokenValidationContextParam();
resourceContextParam.setKey(OAuthConstants.RESOURCE_KEY);
resourceContextParam.setValue(resource);
OAuth2TokenValidationRequestDTO_TokenValidationContextParam[] tokenValidationContextParams =
new OAuth2TokenValidationRequestDTO_TokenValidationContextParam[1];
tokenValidationContextParams[0] = resourceContextParam;
validationRequest.setContext(tokenValidationContextParams);
return validationRequest;
}
}

@ -0,0 +1,64 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.webapp.authenticator.framework.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.wso2.carbon.utils.ServerConstants;
import org.wso2.carbon.webapp.authenticator.framework.AuthenticatorFrameworkException;
import org.wso2.carbon.webapp.authenticator.framework.config.AuthenticatorConfig;
import org.wso2.carbon.webapp.authenticator.framework.config.WebappAuthenticatorConfig;
import java.util.List;
public class WebappAuthenticatorConfigTest {
@BeforeClass
public void init() {
System.setProperty(ServerConstants.CARBON_CONFIG_DIR_PATH, "src/test/resources/config");
}
@Test
public void testConfigInitialization() {
try {
WebappAuthenticatorConfig.init();
WebappAuthenticatorConfig config = WebappAuthenticatorConfig.getInstance();
Assert.assertNotNull(config);
List<AuthenticatorConfig> authConfigs = config.getAuthenticators();
Assert.assertNotNull(authConfigs);
} catch (AuthenticatorFrameworkException e) {
Assert.fail("Error occurred while testing webapp authenticator config initialization", e);
} catch (Throwable e) {
Assert.fail("Unexpected error has been encountered while testing webapp authenticator config " +
"initialization", e);
}
}
@AfterClass
public void cleanup() {
System.setProperty(ServerConstants.CARBON_CONFIG_DIR_PATH, "");
}
}

@ -0,0 +1,106 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.webapp.authenticator.framework.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
import org.wso2.carbon.webapp.authenticator.framework.Utils.OAuthTokenValidationStubFactory;
import java.util.Properties;
public class WebappAuthenticatorFrameworkUtilTest {
private static final Log log = LogFactory.getLog(WebappAuthenticatorFrameworkUtilTest.class);
private static final String TOKEN_VALIDATION_SERVICE_URL = "https://localhost:9443";
private static final String ADMIN_USERNAME = "admin";
private static final String ADMIN_PASSWORD = "admin";
private static final Properties PROPERTIES = new Properties();
static {
PROPERTIES.setProperty("MaxTotalConnections", "100");
PROPERTIES.setProperty("MaxConnectionsPerHost", "100");
}
@Test
public void testOAuthTokenValidatorStubPool() {
ObjectPool stubs = null;
OAuth2TokenValidationServiceStub stub = null;
try {
stubs = new GenericObjectPool(
new OAuthTokenValidationStubFactory(
TOKEN_VALIDATION_SERVICE_URL, ADMIN_USERNAME, ADMIN_PASSWORD, PROPERTIES));
stub = (OAuth2TokenValidationServiceStub) stubs.borrowObject();
Assert.assertNotNull(stub);
} catch (Exception e) {
String msg = "Error occurred while borrowing an oauth validator service stub instance from the pool";
log.error(msg, e);
Assert.fail(msg, e);
} finally {
if (stubs != null) {
try {
if (stub != null) {
stubs.returnObject(stub);
}
} catch (Exception e) {
log.warn("Error occurred while returning oauth validator service stub instance to the pool", e);
}
/* Checks if the stub instance used above has been properly returned to the pool */
Assert.assertEquals(stubs.getNumIdle(), 1);
/* Verifies that there's no hanging connections after the operation performed above */
Assert.assertEquals(stubs.getNumActive(), 0);
try {
stubs.close();
} catch (Exception e) {
log.warn("Error occurred while closing the object pool", e);
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testStubFactoryInitWithInvalidHttpClientProperties() {
new OAuthTokenValidationStubFactory(TOKEN_VALIDATION_SERVICE_URL, null, ADMIN_PASSWORD, PROPERTIES);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testStubFactoryInitWithInvalidUsername() {
new OAuthTokenValidationStubFactory(TOKEN_VALIDATION_SERVICE_URL, null, ADMIN_PASSWORD, PROPERTIES);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testStubFactoryInitWithInvalidPassword() {
new OAuthTokenValidationStubFactory(TOKEN_VALIDATION_SERVICE_URL, ADMIN_USERNAME, null, PROPERTIES);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testStubFactoryInitWithInvalidUrl() {
new OAuthTokenValidationStubFactory(null, ADMIN_USERNAME, ADMIN_PASSWORD, PROPERTIES);
}
}

@ -0,0 +1,28 @@
<WebappAuthenticatorConfig>
<Authenticators>
<Authenticator>
<Name>OAuth</Name>
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.OAuthAuthenticator</ClassName>
<Parameters>
<Parameter Name="TokenValidationEndpointUrl">https://localhost:9443</Parameter>
<Parameter Name="Username">admin</Parameter>
<Parameter Name="Password">admin</Parameter>
<Parameter Name="IsRemote">true</Parameter>
<Parameter Name="MaxConnectionsPerHost">10000</Parameter>
<Parameter Name="MaxTotalConnections">10000</Parameter>
</Parameters>
</Authenticator>
<Authenticator>
<Name>BasicAuth</Name>
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.BasicAuthAuthenticator</ClassName>
</Authenticator>
<Authenticator>
<Name>JWT</Name>
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.JWTAuthenticator</ClassName>
</Authenticator>
<Authenticator>
<Name>CertificateAuth</Name>
<ClassName>org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator</ClassName>
</Authenticator>
</Authenticators>
</WebappAuthenticatorConfig>

@ -0,0 +1,32 @@
#
# Copyright 2009 WSO2, Inc. (http://wso2.com)
#
# Licensed 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.
#
#
# This is the log4j configuration file used by WSO2 Carbon
#
# IMPORTANT : Please do not remove or change the names of any
# of the Appenders defined here. The layout pattern & log file
# can be changed using the WSO2 Carbon Management Console, and those
# settings will override the settings in this file.
#
log4j.rootLogger=ERROR, STD_OUT
# Redirect log messages to console
log4j.appender.STD_OUT=org.apache.log4j.ConsoleAppender
log4j.appender.STD_OUT.Target=System.out
log4j.appender.STD_OUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STD_OUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

@ -0,0 +1,37 @@
<!--
~ Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="WebappAuthenticatorFramework">
<parameter name="useDefaultListeners" value="false"/>
<test name="WebappAuthenticatorConfigTests" preserve-order="true">
<classes>
<class name="org.wso2.carbon.webapp.authenticator.framework.test.WebappAuthenticatorConfigTest"/>
</classes>
</test>
<test name="WebappAuthenticatorUtilTests" preserve-order="true">
<classes>
<class name="org.wso2.carbon.webapp.authenticator.framework.test.WebappAuthenticatorFrameworkUtilTest"/>
</classes>
</test>
</suite>

@ -1263,12 +1263,21 @@
<artifactId>neethi</artifactId>
<version>${neethi.version}</version>
</dependency>
<dependency>
<groupId>commons-pool.wso2</groupId>
<artifactId>commons-pool</artifactId>
<version>${commons.pool.wso2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.wso2</groupId>
<artifactId>httpclient</artifactId>
<version>${httpcomponents.httpclient.version}</version>
</dependency>
<dependency>
<groupId>commons-httpclient.wso2</groupId>
<artifactId>commons-httpclient</artifactId>
<version>${commons.httpclient.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -1380,6 +1389,11 @@
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18</version>
</plugin>
</plugins>
</pluginManagement>
</build>
@ -1564,6 +1578,8 @@
<project.scm.id>github-scm</project.scm.id>
<commons.pool.wso2.version>1.5.6.wso2v1</commons.pool.wso2.version>
<httpcomponents.httpclient.version>4.2.3.wso2v1</httpcomponents.httpclient.version>
<commons.httpclient.version>3.1.0.wso2v2</commons.httpclient.version>
</properties>
</project>

Loading…
Cancel
Save