Skip to content

Commit afab7cb

Browse files
authored
Merge pull request #156 from CyberSource/future
Merge future branch to master
2 parents 9a7eee8 + 6ac3caa commit afab7cb

33 files changed

+1392
-1266
lines changed

README.md

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CyberSource Simple Order API for Java
22

3-
[![Build Status](https://travis-ci.org/CyberSource/cybersource-sdk-java.png?branch=master)](https://travis-ci.org/CyberSource/cybersource-sdk-java)
3+
[![Build Status](https://travis-ci.org/CyberSource/cybersource-sdk-java.png?branch=future)](https://travis-ci.org/CyberSource/cybersource-sdk-java)
44

55
## Package Managers
66

@@ -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
@@ -78,8 +78,11 @@ You do not need to download and build the source to use the SDK but if you want
7878

7979
Note: This number cannot be greater than Maximum Total Connections and every connection created here also counts into Maximum Total Connections.
8080
- `connectionRequestTimeoutMs` Time taken in milliseconds to get connection request from the pool. If it times out, it will throw error as Timeout waiting for connection from pool
81-
- `connectionTimeoutMs` Specifies the number of milliseconds to wait while a connection is being established.
82-
- `socketTimeoutMs` Specifies the time waiting for data – after establishing the connection; maximum time of inactivity between two data packets. Recommanded valut is 130000 (in ms).
81+
- `connectionTimeoutMs` Specifies the number of milliseconds to wait while a connection is being established. With 6.2.11 release onwards, this property can be used for basic
82+
apache http client and JDK provided HttpUrlConnection implementation as well while keeping the backward compatibility with 'timeout' property.
83+
- `socketTimeoutMs` Specifies the time waiting for data – after establishing the connection; maximum time of inactivity between two data packets.
84+
With 6.2.11 release onwards, this property can be used for basic apache http client and JDK provided HttpUrlConnection implementation as well while keeping the
85+
backward compatibility with 'timeout' property.
8386
- `evictThreadSleepTimeMs` Specifies time duration in milliseconds between "sweeps" by the "idle connection" evictor thread.
8487
This thread will check if any idle/expired/stale connections are available in pool and evict it.
8588
- `maxKeepAliveTimeMs` Specifies the time duration in milliseconds that a connection can be idle before it is evicted from the pool.
@@ -185,6 +188,25 @@ keytool -list -v -keystore <Your_keystore_name>`
185188
## Message Level Encryption
186189
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.
187190

191+
## Meta Key support
192+
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.
193+
194+
SOAPI Java SDK supports meta key by default. Additional details regarding cybs.properties.
195+
196+
merchantID= <comment/remove this line>
197+
keysDirectory=<Directory where P12 is present>
198+
keyAlias=<Refers to the portfolio>
199+
keyPassword=<Password of p12>
200+
targetAPIVersion=<latest API version, refer here https://ics2ws.ic3.com/commerce/1.x/transactionProcessor>
201+
keyFilename= <metakey downloaded from portfolio MID>
202+
203+
Auth sample payload:
204+
205+
merchantID=<meta_2232323> <Refers to the Child transactional MID>
206+
ccAuthService_run=true
207+
merchantReferenceCode=MRC-14344
208+
billTo_firstName=John
209+
188210
### Authentication Details
189211
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.
190212
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 +235,30 @@ Retry Pattern allows to retry sending a failed request and it will only work wit
213235
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.
214236
4. org.apache.commons:commons-lang3:3.4
215237
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
238+
5. commons-logging:commons-logging:jar:1.1.1
219239
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
240+
6. org.slf4j:slf4j-api:1.7.21 and org.slf4j:slf4j-jcl:1.7.21
221241
slf4j-api is getting used as a dependency for wss4j. Modified to latest version.
222-
8. junit:junit:4.12
242+
7. junit:junit:4.13.1
223243
JUnit is a unit testing framework for Java.
224-
9. org.mockito:mockito-all:1.10.19
244+
8. org.mockito:mockito-all:1.10.19
225245
Mock objects library for java
226-
10. org.apache.httpcomponents:httpclient:4.5.11
246+
9. org.apache.httpcomponents:httpclient:4.5.13
227247
Provides reusable components for client-side authentication, HTTP state management, and HTTP connection management. It is used for poolinghttpclientconnectionmanager feature.
228-
248+
10. org.apache.httpcomponents:httpcore:4.4.13
249+
Provides low level HTTP transport components that can be used to build custom client and server side HTTP services with a minimal footprint.
229250

230251
## Changes
231252
_______________________________
253+
Version Cybersource-sdk-java 6.2.11 (MAY,2020)
254+
_______________________________
255+
1)Exception handling improvement.
256+
2)Upgrading Apache's basic http client functionality.
257+
3)Upgrading org.apache.httpcomponents:httpclient:4.5.11 to org.apache.httpcomponents:httpclient:4.5.13 because of CVE-2020-13956 vulnerability.
258+
4)ReadMe changes for meta key support.
259+
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)
260+
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.
261+
_______________________________
232262
Version Cybersource-sdk-java 6.2.10 (MAY,2020)
233263
_______________________________
234264
1)Added PoolingHttpClientConnection implementation
@@ -330,8 +360,6 @@ _______________________________
330360
// or
331361
String stackTrace = Utility.getStackTrace(e.getInnerException() != null? e.getInnerException(): e);
332362
}
333-
334-
335363
336364
## Documentation
337365
- 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)