I am trying to create a Connection Pool with single connection using PoolingHttpClientConnectionManager and ClosableHttpClient for HTTPS and reuse it - ssl

Trying to create a connection pool, where only single HTTPS connection will be created and when subsequent request comes previous connection pool would be used. Currently when I am trying to hit any request each time new connection is getting Established and previous connection is going into time wait state.
Below code-snippet I am using, it's working for HTTP connection but not for HTTPS
SslConfigurator sslConfig = SslConfigurator.newInstance().keyStoreFile(this.connectionInfo.getKeyStorePath()).keyStorePassword(connectionInfo.getKeyStorePassword()).keyStoreType("JKS").trustStoreFile(this.connectionInfo.getKeyStorePath()).trustStorePassword(connectionInfo.getKeyStorePassword()).securityProtocol("TLS");
logger.info("SSL CONFIG Accepted");
sslContext = sslConfig.createSSLContext();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE);
logger.info("SSL CONTEXT CREATED, Building Client" );
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslsf).build();
connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connManager.setMaxTotal(1);
connManager.setDefaultMaxPerRoute(1);
config = RequestConfig.custom().setConnectTimeout(60000).setConnectionRequestTimeout(60000).setSocketTimeout(60000).build();
client = HttpClients.custom().setDefaultRequestConfig(config).setConnectionManager(connManager).build();

connManager.setMaxTotal(1);
I am not sure why you think this has no effect because this should definitely restrict the total number of connections in the pool to just one at a time.
In your particular case however you should be using BasicHttpClientConnectionManager instead of PoolingHttpClientConnectionManager

Related

.Net Core ReportExecutionServiceSoapClient set credentials

I am using ReportExecutionServiceSoapClient in .Net Core i got the latest version of .net Core and tried to get a report from reporting services to work. after I've used the WCF connection service I was able to add the code with looks like bellow
// Instantiate the Soap client
ReportExecutionServiceSoap rsExec = new ReportExecutionServiceSoapClient(ReportExecutionServiceSoapClient.EndpointConfiguration.ReportExecutionServiceSoap);
// Create a network credential object with the appropriate username and password used
// to access the SSRS web service
string historyID = null;
TrustedUserHeader trustedUserHeader = new TrustedUserHeader();
ExecutionHeader execHeader = new ExecutionHeader();
// Here we call the async LoadReport() method using the "await" keyword, which means any code below this method
// will not execute until the result from the LoadReportAsync task is returned
var taskLoadReport = rsExec.LoadReportAsync(reportPath, historyID);
// By the time the LoadReportAsync task is returned successfully, its "executionInfo" property
// would have already been populated. Now the remaining code in this main thread will resume executing
string deviceInfo = null;
string format = "EXCEL";
// Now, similar to the above task, we will call the RenderAsync() method and await its result
var taskRender = await rsExec.RenderAsync(renderReq);
When it hist renderAsync all falls apart because the credentials for the service are not set anywhere. I've tried to Login async with no success. Also I've tried to set the credentials with SetExecutionCredentialsAsync but I've got and error saying "The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'NTLM'." I don't know how to change that for ReportExecutionServiceSoapClient.
I have read some posts in which Microsoft guys says that the authentication with a soap is not resolved but for me it seems so close to be true. I feel like I am missing something.
Technology stack: VS 2017, .net Core web api, ssrs 2016, sql server 2016 standard
How can I authenticate the user for this call?
I know this is an old question but I had the same issue and stumbled onto the answer.
After creating the ReportExecutionServiceSoap object you can specify the username and password in the ClientCredentials. I've had success with this using the Basic client credential type. Be sure you are using HTTPS, otherwise your password is sent in plaintext to the reporting server. I also recommend storing the user/password in a secure place and not code.
BasicHttpBinding rsBinding = new BasicHttpBinding();
rsBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
rsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress rsEndpointAddress = new EndpointAddress("https://servername/ReportServer/ReportExecution2005.asmx");
var rsExec = new ReportExecutionServiceSoapClient(rsBinding, rsEndpointAddress);
rsExec.ClientCredentials.UserName.UserName = "username";
rsExec.ClientCredentials.UserName.Password = "pass";

Apache HTTP client only two connections are possible

I have below code to invoke a REST API method using Apache HTTP client. However only two parallel requests could be sent using above client.
Is there any parameter to set max-connections?
HttpPost post = new HttpPost(resourcePath);
addPayloadJsonString(payload, post);//set a String Entity
setAuthHeader(post);// set Authorization: Basic header
try {
return httpClient.execute(post);
} catch (IOException e) {
String errorMsg = "Error while executing POST statement";
log.error(errorMsg, e);
throw new RestClientException(errorMsg, e);
}
Jars I am using are below are,
org.apache.httpcomponents.httpclient_4.3.5.jar
org.apache.httpcomponents.httpcore_4.3.2.jar
You can configure the HttpClient with HttpClientConnectionManager
Take a look at Pooling connection manager.
ClientConnectionPoolManager maintains a pool of HttpClientConnections and is able to service connection requests from multiple execution threads. Connections are pooled on a per route basis. A request for a route which already the manager has persistent connections for available in the pool will be services by leasing a connection from the pool rather than creating a brand new connection.
PoolingHttpClientConnectionManager maintains a maximum limit of connections on a per route basis and in total. Per default this implementation will create no more than 2 concurrent connections per given route and no more 20 connections in total. For many real-world applications these limits may prove too constraining, especially if they use HTTP as a transport protocol for their services.
This example shows how the connection pool parameters can be adjusted:
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
// Increase max total connection to 200
cm.setMaxTotal(200);
// Increase default max connection per route to 20
cm.setDefaultMaxPerRoute(20);
// Increase max connections for localhost:80 to 50
HttpHost localhost = new HttpHost("locahost", 80);
cm.setMaxPerRoute(new HttpRoute(localhost), 50);
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.build();

org.restlet.Context timeout value

When org.restlet.Context is using Apache HttpClient to make the connection, how do I specify the timeout period the client should wait for the server to respond. Here is what I have so far
final Context context = new Context();
context.getParameters().add("socketTimeout", "10000");
context.getParameters().add("", "10000"); //?? connectionTimeout
ClientResource clientResource = new ClientResource(context, ss.getUrl());
Is there documentation for the possible parameter values and their meaning?
In fact, all supported parameters for the HttpClient extension are described in this page:
http://www.restlet.org/documentation/snapshot/jee/ext/org/restlet/ext/httpclient/HttpClientHelper.html
In your case, it seems that the idleTimeout parameter should bother.

cxf failover recovery

I have a cxf JAX-WS client. I added the failover strategy. The question is how the client can recovery from the backup solution and use again the primary URL? Because now after the client will switch to secondary URL remains there, will not use the primary URL even if this become available again.
The code for the client part is:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(GatewayPort.class);
factory.setAddress(this.configFile.getPrimaryURL());
FailoverFeature feature = new FailoverFeature();
SequentialStrategy strategy = new SequentialStrategy();
List<String> addList = new ArrayList<String>();
addList.add(this.configFile.getSecondaryURL());
strategy.setAlternateAddresses(addList);
feature.setStrategy(strategy);
List<AbstractFeature> features = new ArrayList<AbstractFeature>();
features.add(feature);
factory.setFeatures(features);
this.serviceSoap = (GatewayPort)factory.create();
Client client = ClientProxy.getClient(this.serviceSoap);
if (client != null)
{
HTTPConduit conduit = (HTTPConduit)client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(this.configFile.getTimeout());
policy.setReceiveTimeout(this.configFile.getTimeout());
conduit.setClient(policy);
}
You may add the primary URL to the alternate addresses list instead of setting that to JaxWsProxyFactoryBean. This way, since you are using SequentialStrategy, the primary URL will be checked first for every service call, if it fails then secodary URL will be tried.
You might as well try an alternative CXF failover feture with failback.
https://github.com/jaceko/cxf-circuit-switcher

Where do I specify proxy credentials in my WCF client?

I have created a WCF client using channel factory.
But I am not able to connect to a server in another machine. I am getting a (407) Prxy Authentication Required exception.
WSHttpBinding wsBinding = new WSHttpBinding();
wsBinding.BypassProxyOnLocal = true;
EndpointAddress endpoint =
new EndpointAddress("http://machineName:7676/MyWCFService");
ChannelFactory<IService> sericeInterface =
new ChannelFactory<IService>(wsBinding, endpoint);
sericeInterface.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
sericeInterface = sericeInterface.CreateChannel();
This is my client connection code nippet. I am getting exception when I call a method of the service.
Take a look at this CodePlex link, try to find a scenario that matches closely to yours. It provides checklists and samples of how to set the various credentials for different situations/bindings.
Also this MSDN link might help with Windows Authentication, which you seem to be using.
To assign credentials you'll need something like the below taken from the MSDN link:
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
// This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName();
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword();