Skip to content

Commit 8900dd1

Browse files
authored
Merge pull request #149 from mahendya1002/future
Merging code for below changes. 1) SDK vulnerability issue for httpclient3.1 version 2) Separate out connection and socket timeout prop. Right now both are set via timeout property in case of jdk HttpUrlConnectiona and Apache basic http client. Make sure you have backward compatibility. 3) Set default sockettimeout(readTimeout) value to 130000ms(130secs) in cybs.properties file. 4) Http request retry is added in case of HttpPoolingClient when 'javax.net.ssl.SSLException:Connection reset' exception is thrown(specific to jdk8u261 & + version refer this https://bugs.openjdk.java.net/browse/JDK-8214339) 5) Upgraded Junit lib version. 6) Make SDK exception handling better and minor code refactoring.
2 parents ff6ae2f + a0f33b1 commit 8900dd1

33 files changed

+1382
-1261
lines changed

README.md

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ To install the `cybersource-sdk-java` from central repository, add dependency to
1010
<dependency>
1111
<groupId>com.cybersource</groupId>
1212
<artifactId>cybersource-sdk-java</artifactId>
13-
<version>6.2.10</version>
13+
<version>6.2.11</version>
1414
</dependency>
1515
```
1616
Run `mvn install` to install dependency
@@ -19,7 +19,7 @@ Run `mvn install` to install dependency
1919
Add the dependency to your build.gradle
2020
```java
2121
dependencies {
22-
compile 'com.cybersource:cybersource-sdk-java:6.2.10'
22+
compile 'com.cybersource:cybersource-sdk-java:6.2.11'
2323
}
2424
```
2525
## Requirements
@@ -185,6 +185,25 @@ keytool -list -v -keystore <Your_keystore_name>`
185185
## Message Level Encryption
186186
CyberSource supports Message Level Encryption (MLE) for Simple Order API. Message level encryption conforms to the SOAP Security 1.0 specification published by the OASIS standards group.
187187

188+
## Meta Key support
189+
Meta Key is a key generated by an entity that can be used to authenticate on behalf of other entities provided that the entity which holds key is a parent entity or associated as a partner.
190+
191+
SOAPI Java SDK supports meta key by default. Additional details regarding cybs.properties.
192+
193+
merchantID= <comment/remove this line>
194+
keysDirectory=<Directory where P12 is present>
195+
keyAlias=<Refers to the portfolio>
196+
keyPassword=<Password of p12>
197+
targetAPIVersion=<latest API version, refer here https://ics2ws.ic3.com/commerce/1.x/transactionProcessor>
198+
keyFilename= <metakey downloaded from portfolio MID>
199+
200+
Auth sample payload:
201+
202+
merchantID=<meta_2232323> <Refers to the Child transactional MID>
203+
ccAuthService_run=true
204+
merchantReferenceCode=MRC-14344
205+
billTo_firstName=John
206+
188207
### Authentication Details
189208
Message level encryption authenticates using the same mechanism as signed SOAP messages. The signature creation involves utilizing the merchants private key which combined with a hash of the message to be signed, can be validated with the merchants certificate and the message which was signed.
190209
The merchant certificate is included in the SOAP message for both signature and message level encryption. Message level encryption, encrypts a temporary message key for a specific recipient. This is done by encrypting the temporary message key with the recipient’s public certificate. Therefore only the party holding the private key (CyberSource) can decrypt the temporary message key. The merchant sending the request must be a valid merchant for the environment which the message is being processed in. After validating the merchant and retrieving the CyberSource copy of the merchant certificate from our database, these additional authentication steps are performed:
@@ -213,22 +232,30 @@ Retry Pattern allows to retry sending a failed request and it will only work wit
213232
The XML Security project is aimed at providing implementation of security standards for XML,supports XML-Signature Syntax and Processing,XML Encryption Syntax and Processing, and supports XML Digital Signature APIs.
214233
4. org.apache.commons:commons-lang3:3.4
215234
Apache Commons Lang, a package of Java utility classes for the classes that are in java.lang's hierarchy, or are considered to be so standard as to justify existence in java.lang.
216-
5. commons-httpclient:commons-httpclient:3.1
217-
Provides a framework by which new request types (methods) or HTTP extensions can be created easily.
218-
6. commons-logging:commons-logging:jar:1.1.1
235+
5. commons-logging:commons-logging:jar:1.1.1
219236
This is getting downloaded as compile time dependency of wss4j:1.6.19.Apache Commons Logging is a thin adapter allowing configurable bridging to other, well known logging systems.
220-
7. org.slf4j:slf4j-api:1.7.21 and org.slf4j:slf4j-jcl:1.7.21
237+
6. org.slf4j:slf4j-api:1.7.21 and org.slf4j:slf4j-jcl:1.7.21
221238
slf4j-api is getting used as a dependency for wss4j. Modified to latest version.
222-
8. junit:junit:4.12
239+
7. junit:junit:4.13.1
223240
JUnit is a unit testing framework for Java.
224-
9. org.mockito:mockito-all:1.10.19
241+
8. org.mockito:mockito-all:1.10.19
225242
Mock objects library for java
226-
10. org.apache.httpcomponents:httpclient:4.5.11
243+
9. org.apache.httpcomponents:httpclient:4.5.13
227244
Provides reusable components for client-side authentication, HTTP state management, and HTTP connection management. It is used for poolinghttpclientconnectionmanager feature.
228-
245+
10. org.apache.httpcomponents:httpcore:4.4.13
246+
Provides low level HTTP transport components that can be used to build custom client and server side HTTP services with a minimal footprint.
229247

230248
## Changes
231249
_______________________________
250+
Version Cybersource-sdk-java 6.2.11 (JUNE,2020)
251+
_______________________________
252+
1)Exception handling improvement.
253+
2)Upgrading Apache's basic http client functionality.
254+
3)Upgrading org.apache.httpcomponents:httpclient:4.5.11 to org.apache.httpcomponents:httpclient:4.5.13 because of CVE-2020-13956 vulnerability.
255+
4)ReadMe changes for meta key support.
256+
5)Http request retry is added in case of HttpPoolingClient when 'javax.net.ssl.SSLException:Connection reset' exception is thrown(specific to jdk8u251 & + version refer this https://bugs.openjdk.java.net/browse/JDK-8214339)
257+
6)Separate out connection and socket timeout prop. Right now both are set via timeout property in case of jdk HttpUrlConnectiona and Apache basic http client.
258+
_______________________________
232259
Version Cybersource-sdk-java 6.2.10 (MAY,2020)
233260
_______________________________
234261
1)Added PoolingHttpClientConnection implementation
@@ -330,8 +357,6 @@ _______________________________
330357
// or
331358
String stackTrace = Utility.getStackTrace(e.getInnerException() != null? e.getInnerException(): e);
332359
}
333-
334-
335360
336361
## Documentation
337362
- For more information about CyberSource services, see <https://www.cybersource.com/en-us/support/technical-documentation.html>.

java/pom.xml

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@
219219
<dependency>
220220
<groupId>junit</groupId>
221221
<artifactId>junit</artifactId>
222-
<version>4.12</version>
222+
<version>4.13.1</version>
223223
<scope>test</scope>
224224
</dependency>
225225
<dependency>
@@ -235,26 +235,15 @@
235235
<dependency>
236236
<groupId>org.apache.httpcomponents</groupId>
237237
<artifactId>httpclient</artifactId>
238-
<version>4.5.11</version>
238+
<version>4.5.13</version>
239239
<exclusions>
240240
<exclusion>
241241
<groupId>commons-logging</groupId>
242242
<artifactId>commons-logging</artifactId>
243243
</exclusion>
244244
</exclusions>
245245
</dependency>
246-
<dependency>
247-
<groupId>commons-httpclient</groupId>
248-
<artifactId>commons-httpclient</artifactId>
249-
<version>3.1</version>
250-
<exclusions>
251-
<exclusion>
252-
<groupId>commons-logging</groupId>
253-
<artifactId>commons-logging</artifactId>
254-
</exclusion>
255-
</exclusions>
256-
</dependency>
257-
<dependency>
246+
<dependency>
258247
<groupId>org.bouncycastle</groupId>
259248
<artifactId>bcprov-jdk15on</artifactId>
260249
<version>1.61</version>

java/src/main/java/com/cybersource/ws/client/ClientException.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
*/
2727
public class ClientException
2828
extends Exception {
29-
private Exception innerException = null;
29+
private Exception innerException;
3030
private boolean critical = false;
3131
private int httpStatusCode = -1;
32-
private String httpError = null;
32+
private String httpError;
3333

3434
/**
3535
*
@@ -38,6 +38,7 @@ public class ClientException
3838
*/
3939
public ClientException(
4040
Exception _innerException, Logger logger) {
41+
super(_innerException);
4142
innerException = _innerException;
4243
log(logger);
4344
}
@@ -52,6 +53,7 @@ public ClientException(
5253
*/
5354
public ClientException(
5455
Exception _innerException, boolean _critical, Logger logger) {
56+
super(_innerException);
5557
innerException = _innerException;
5658
critical = _critical;
5759
log(logger);
@@ -77,7 +79,10 @@ public ClientException(int _httpStatusCode, Logger logger) {
7779
*/
7880
public ClientException(
7981
int _httpStatusCode, String _httpError, Logger logger) {
80-
this(_httpStatusCode, logger);
82+
super(_httpError);
83+
httpStatusCode = _httpStatusCode;
84+
critical
85+
= (_httpStatusCode == HttpURLConnection.HTTP_GATEWAY_TIMEOUT);
8186
httpError = _httpError;
8287
log(logger);
8388
}
@@ -94,8 +99,7 @@ public ClientException(
9499
public ClientException(
95100
int _httpStatusCode, String _httpError, boolean _critical,
96101
Logger logger) {
97-
this(_httpStatusCode, logger);
98-
httpError = _httpError;
102+
this(_httpStatusCode, _httpError, logger);
99103

100104
// if critical is already true (the other constructor invoked in the
101105
// first line may set it to true), don't bother setting it as we don't
@@ -169,28 +173,24 @@ void log(Logger logger) {
169173
* @return a string representation of the object for logging purposes.
170174
*/
171175
String getLogString() {
172-
StringBuffer sb = new StringBuffer("ClientException details:\n");
176+
StringBuilder sb = new StringBuilder("ClientException details:\n");
173177

174178
if (critical) {
175179
sb.append("CRITICAL\n");
176180
}
177181

178182
if (httpStatusCode != -1) {
179-
sb.append("httpStatusCode = " + httpStatusCode + "\n");
183+
sb.append("httpStatusCode = ").append(httpStatusCode).append("\n");
180184
}
181185

182186
if (httpError != null) {
183-
sb.append("httpError = " + httpError + "\n");
187+
sb.append("httpError = ").append(httpError).append("\n");
184188
}
185189

186190
if (innerException != null) {
187-
sb.append(
188-
"innerException: \n" +
189-
Utility.getStackTrace(innerException));
191+
sb.append("innerException: \n").append(Utility.getStackTrace(innerException));
190192
} else {
191-
sb.append(
192-
"Stack trace: \n" +
193-
Utility.getStackTrace(this));
193+
sb.append("Stack trace: \n").append(Utility.getStackTrace(this));
194194
}
195195

196196
return (sb.toString());
@@ -204,13 +204,13 @@ String getLogString() {
204204
public String getMessage() {
205205
if (innerException != null) return innerException.getMessage();
206206

207-
StringBuffer sb = new StringBuffer("ClientException:");
207+
StringBuilder sb = new StringBuilder("ClientException:");
208208
if (httpStatusCode != -1) {
209-
sb.append(" (" + httpStatusCode + ")");
209+
sb.append(" (").append(httpStatusCode).append(")");
210210
}
211211

212212
if (httpError != null) {
213-
sb.append(" " + httpError);
213+
sb.append(" ").append(httpError);
214214
}
215215

216216
if (critical) {

java/src/main/java/com/cybersource/ws/client/ConfigException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ public class ConfigException extends Exception {
3232
public ConfigException(String message) {
3333
super(message);
3434
}
35+
36+
public ConfigException(String message, Throwable cause) {
37+
super(message, cause);
38+
}
3539
}

java/src/main/java/com/cybersource/ws/client/ConnectionHelper.java

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818

1919
package com.cybersource.ws.client;
2020

21+
import org.apache.http.HttpHost;
22+
import org.apache.http.auth.AuthScope;
23+
import org.apache.http.auth.UsernamePasswordCredentials;
24+
import org.apache.http.client.CredentialsProvider;
25+
import org.apache.http.client.config.AuthSchemes;
26+
import org.apache.http.client.config.RequestConfig;
27+
import org.apache.http.impl.client.BasicCredentialsProvider;
28+
import org.apache.http.impl.client.HttpClientBuilder;
29+
import org.apache.http.impl.client.ProxyAuthenticationStrategy;
30+
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
2131
import org.bouncycastle.util.encoders.Base64;
2232

2333
import java.io.IOException;
@@ -26,6 +36,7 @@
2636
import java.net.Proxy;
2737
import java.net.URL;
2838
import java.nio.charset.Charset;
39+
import java.util.Collections;
2940

3041
/**
3142
* Helps in creating the Proxy and adding Proxy credentials to JDKHttpURLConnection.
@@ -45,12 +56,11 @@ public static boolean getDefaultUseHttpClient() {
4556
/**
4657
* Sets the timeout for HTTP Request
4758
* @param con - HttpURLConnection
48-
* @param timeout - timeout integer value
59+
* @param mc - MerchantConfig
4960
*/
50-
public static void setTimeout(HttpURLConnection con, int timeout) {
51-
int timeoutInMS = timeout * 1000;
52-
con.setConnectTimeout(timeoutInMS);
53-
con.setReadTimeout(timeoutInMS);
61+
public static void setTimeout(HttpURLConnection con, MerchantConfig mc) {
62+
con.setConnectTimeout(mc.getConnectionTimeoutMs());
63+
con.setReadTimeout(mc.getSocketTimeoutMs());
5464
}
5565

5666
/**
@@ -108,4 +118,30 @@ private static void addProxyCredentials(
108118

109119
}
110120
}
121+
122+
/**
123+
* Set proxy by using proxy credentials to create httpclient
124+
*
125+
* @param httpClientBuilder
126+
* @param requestConfigBuilder
127+
* @param merchantConfig
128+
*/
129+
public static void setProxy(HttpClientBuilder httpClientBuilder, RequestConfig.Builder requestConfigBuilder, MerchantConfig merchantConfig) {
130+
if (merchantConfig.getProxyHost() != null) {
131+
HttpHost proxy = new HttpHost(merchantConfig.getProxyHost(), merchantConfig.getProxyPort());
132+
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
133+
httpClientBuilder.setRoutePlanner(routePlanner);
134+
135+
if (merchantConfig.getProxyUser() != null) {
136+
httpClientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
137+
requestConfigBuilder.setProxyPreferredAuthSchemes(Collections.singletonList(AuthSchemes.BASIC));
138+
139+
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
140+
credentialsProvider.setCredentials(AuthScope.ANY,
141+
new UsernamePasswordCredentials(merchantConfig.getProxyUser(), merchantConfig.getProxyPassword()));
142+
143+
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
144+
}
145+
}
146+
}
111147
}

java/src/main/java/com/cybersource/ws/client/FaultException.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
public class FaultException
2828
extends Exception {
2929
private final Document faultDocument;
30-
private String faultCode = null;
31-
private String faultString = null;
32-
private String requestID = null;
30+
private String faultCode;
31+
private String faultString;
32+
private String requestID;
3333
private boolean critical = true;
3434

3535
/**
@@ -106,7 +106,7 @@ private void extractFields(String nsURI) {
106106
faultCode
107107
= Utility.getElementText(faultDocument, "faultcode", null);
108108

109-
int colonPos = faultCode.indexOf(":");
109+
int colonPos = faultCode!=null? faultCode.indexOf(":"): -1;
110110
String localPart
111111
= (colonPos != -1)
112112
? faultCode.substring(colonPos + 1)
@@ -133,14 +133,14 @@ void log(Logger logger) {
133133
* @return a string representation of the object for logging purposes.
134134
*/
135135
String getLogString() {
136-
StringBuffer sb = new StringBuffer("FaultException details:\n");
136+
StringBuilder sb = new StringBuilder("FaultException details:\n");
137137

138138
if (critical) {
139139
sb.append("CRITICAL\n");
140140
}
141141

142142
if (requestID != null) {
143-
sb.append("requestID = " + requestID + "\n");
143+
sb.append("requestID = ").append(requestID).append("\n");
144144
}
145145

146146
sb.append(Utility.nodeToString(faultDocument));
@@ -154,13 +154,13 @@ String getLogString() {
154154
* @return a description of the exception.
155155
*/
156156
public String getMessage() {
157-
StringBuffer sb = new StringBuffer("Fault:");
157+
StringBuilder sb = new StringBuilder("Fault:");
158158
if (faultString != null) {
159-
sb.append(" " + faultString);
159+
sb.append(" ").append(faultString);
160160
}
161161

162162
if (requestID != null) {
163-
sb.append(" (requestID=" + requestID + ")");
163+
sb.append(" (requestID=").append(requestID).append(")");
164164
}
165165

166166
if (critical) {

0 commit comments

Comments
 (0)