Skip to content

Commit 9e8c471

Browse files
Release 7.0.0
1 parent 3dcd247 commit 9e8c471

File tree

8 files changed

+321
-81
lines changed

8 files changed

+321
-81
lines changed

README.md

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Add this dependency to your project's POM:
2323
<dependency>
2424
<groupId>ch.postfinance</groupId>
2525
<artifactId>postfinancecheckout-java-sdk</artifactId>
26-
<version>6.2.0</version>
26+
<version>7.0.0</version>
2727
<scope>compile</scope>
2828
</dependency>
2929
```
@@ -33,7 +33,7 @@ Add this dependency to your project's POM:
3333
Add this dependency to your project's build file:
3434

3535
```groovy
36-
compile "ch.postfinance:postfinancecheckout-java-sdk:6.2.0"
36+
compile "ch.postfinance:postfinancecheckout-java-sdk:7.0.0"
3737
```
3838

3939
### Others
@@ -46,7 +46,7 @@ mvn clean package
4646

4747
Then manually install the following JARs:
4848

49-
* `target/postfinancecheckout-java-sdk-6.2.0.jar`
49+
* `target/postfinancecheckout-java-sdk-7.0.0.jar`
5050
* `target/lib/*.jar`
5151

5252
## Usage
@@ -155,6 +155,43 @@ public class TransactionPaymentPageExample {
155155
}
156156

157157
```
158+
Consider using the following overloaded ApiClient constructor and following code snippet to gain access to a resource behind a **proxy** server with a Basic Authentication scheme
159+
```java
160+
// Create an instance of the ApiClient with the user's unique credentials and proxy information.
161+
ApiClient apiClient = new ApiClient(userId, secret, String proxyHostname, int proxyPort);
162+
163+
Authenticator authenticator = new Authenticator() {
164+
@Override
165+
protected PasswordAuthentication getPasswordAuthentication() {
166+
// Check if the authentication request is for a proxy
167+
if (getRequestorType() == RequestorType.PROXY) {
168+
// Check if the authentication scheme is Basic
169+
if ("Basic".equalsIgnoreCase(getRequestingScheme())) {
170+
// Return the PasswordAuthentication instance with the proxy credentials
171+
return new PasswordAuthentication(proxyUsername, proxyPassword.toCharArray());
172+
}
173+
}
174+
175+
return null;
176+
}
177+
};
178+
179+
// Set the default Authenticator that will be used by the networking code when a proxy or an HTTP server asks for authentication.
180+
// Authenticator.setDefault will set the java.net.Authenticator that processes all authentication requests.
181+
Authenticator.setDefault(authenticator);
182+
```
183+
### Disable Basic authentication for HTTPS tunneling
184+
185+
>In some environments, certain authentication schemes may be undesirable when proxying HTTPS. Accordingly, the Basic authentication scheme has been deactivated, by default, in the Oracle
186+
>Java Runtime, by adding Basic to the jdk.http.auth.tunneling.disabledSchemes networking property. Now, proxies requiring Basic authentication when setting up a tunnel for HTTPS
187+
>will no longer succeed by default. If required, this authentication scheme can be reactivated by removing Basic from the jdk.http.auth.tunneling.disabledSchemes networking
188+
>property, or by setting a system property of the same name to "" ( empty ) on the command line.
189+
190+
```java
191+
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
192+
System.setProperty("jdk.http.auth.proxying.disabledSchemes", "");
193+
```
194+
158195
## Recommendation
159196

160197
It is recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apply plugin: 'idea'
22
apply plugin: 'eclipse'
33

44
group = 'ch.postfinance'
5-
version = '6.2.0'
5+
version = '7.0.0'
66

77
buildscript {
88
repositories {
@@ -105,7 +105,7 @@ ext {
105105

106106
dependencies {
107107
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
108-
compile "com.google.api-client:google-api-client:${google_api_client_version}" {
108+
compile ("com.google.api-client:google-api-client:$google_api_client_version") {
109109
exclude group: 'commons-codec', module: 'commons-codec'
110110
}
111111
compile "com.google.guava:guava:$guava_version"

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ lazy val root = (project in file(".")).
22
settings(
33
organization := "ch.postfinance",
44
name := "postfinancecheckout-java-sdk",
5-
version := "6.2.0",
5+
version := "7.0.0",
66
scalaVersion := "2.11.4",
77
scalacOptions ++= Seq("-feature"),
88
javacOptions in compile ++= Seq("-Xlint:deprecation"),

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<artifactId>postfinancecheckout-java-sdk</artifactId>
66
<packaging>jar</packaging>
77
<name>postfinancecheckout-java-sdk</name>
8-
<version>6.2.0</version>
8+
<version>7.0.0</version>
99
<url>https://postfinance.ch/en/business/products/e-commerce/postfinance-checkout-all-in-one.html</url>
1010
<description>The SDK for simplifying the integration with PostFinance Checkout API.</description>
1111
<scm>
@@ -69,8 +69,8 @@
6969
<configuration>
7070
<rules>
7171
<requireMavenVersion>
72-
<version>(,3.9)</version>
73-
<message>Invalid Maven version. It should, at least, be 2.0</message>
72+
<version>[3.2,3.8]</version>
73+
<message>Invalid Maven version. It should be between 3.2 and 3.8 inclusive.</message>
7474
</requireMavenVersion>
7575
</rules>
7676
</configuration>

src/main/java/ch/postfinance/sdk/ApiClient.java

Lines changed: 121 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,51 @@
11
package ch.postfinance.sdk;
22

33
import ch.postfinance.sdk.service.*;
4+
5+
import java.net.InetSocketAddress;
6+
import java.net.Proxy;
47
import java.util.HashMap;
58
import java.util.Map;
9+
610
import com.fasterxml.jackson.annotation.JsonInclude;
711
import com.fasterxml.jackson.databind.DeserializationFeature;
812
import com.fasterxml.jackson.databind.ObjectMapper;
913
import com.fasterxml.jackson.databind.SerializationFeature;
1014
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
1115
import com.google.api.client.http.AbstractHttpContent;
12-
import com.google.api.client.http.HttpRequest;
1316
import com.google.api.client.http.HttpRequestFactory;
14-
import com.google.api.client.http.HttpRequestInitializer;
1517
import com.google.api.client.http.javanet.NetHttpTransport;
1618
import com.google.api.client.json.Json;
17-
import com.google.api.client.http.HttpHeaders;
1819

1920
import java.io.IOException;
2021
import java.io.OutputStream;
2122

23+
/**
24+
* The ApiClient class is responsible for setting up and maintaining the state and configuration
25+
* necessary to interact with a remote API service.
26+
*/
2227

2328
public class ApiClient {
29+
30+
private static final String DEFAULT_BASE_PATH = "https://checkout.postfinance.ch:443/api";
31+
32+
// Configuration fields
2433
private int readTimeOut = 25;
25-
private final String basePath;
26-
private final HttpRequestFactory httpRequestFactory;
27-
private final ObjectMapper objectMapper;
28-
private final long userId;
29-
private final String applicationKey;
30-
private final Map<String, String> defaultHeaders;
34+
private String basePath;
35+
private HttpRequestFactory httpRequestFactory;
36+
private ObjectMapper objectMapper;
37+
private long userId;
38+
private String applicationKey;
39+
private Map<String, String> defaultHeaders = new HashMap<>();
3140

32-
// A reasonable default object mapper. Client can pass in a chosen ObjectMapper anyway, this is just for reasonable defaults.
41+
// Proxy settings
42+
private String proxyHostname;
43+
private int proxyPort;
44+
45+
/**
46+
* Creates a default ObjectMapper for JSON serialization/deserialization.
47+
* This mapper will ignore unknown properties and set proper date formats among other configurations.
48+
*/
3349
private static ObjectMapper createDefaultObjectMapper() {
3450
ObjectMapper objectMapper = new ObjectMapper()
3551
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
@@ -40,60 +56,121 @@ private static ObjectMapper createDefaultObjectMapper() {
4056
return objectMapper;
4157
}
4258

43-
44-
/**
45-
* Constructor for ApiClient
46-
*
47-
* @param userId
48-
* @param applicationKey
49-
*/
50-
public ApiClient(long userId, String applicationKey) {
51-
this(userId, applicationKey, "https://checkout.postfinance.ch:443/api");
52-
}
53-
5459
/**
55-
* Constructor for ApiClient
56-
*
57-
* @param userId
58-
* @param applicationKey
59-
*/
60-
public ApiClient(long userId, String applicationKey, String basePath) {
60+
* Validates the primary inputs required for establishing a connection with the API.
61+
*
62+
* @param userId The user ID that will be authenticated.
63+
* @param applicationKey The application key corresponding to the user's account, used for authentication.
64+
* @param basePath The base URL for the API against which all the requests would be made.
65+
* @throws IllegalArgumentException if any argument does not meet the criteria.
66+
*/
67+
private void validateInputs(long userId, String applicationKey, String basePath) {
6168
if (applicationKey == null || applicationKey.trim().isEmpty()) {
62-
throw new IllegalArgumentException("The application key cannot be empty or null.");
69+
throw new IllegalArgumentException("Application key cannot be null or empty.");
6370
}
6471
if (userId < 1) {
65-
throw new IllegalArgumentException("The user id is invalid.");
72+
throw new IllegalArgumentException("User ID must be positive.");
6673
}
6774
if (basePath == null || basePath.trim().isEmpty()) {
68-
throw new IllegalArgumentException("The base path cannot be empty.");
69-
}
70-
71-
this.basePath = basePath;
75+
throw new IllegalArgumentException("Base path cannot be null or empty.");
76+
}
77+
}
78+
79+
/**
80+
* Initializes common properties for the API client.
81+
*/
82+
private void initializeBaseProperties(long userId, String applicationKey, String basePath) {
83+
validateInputs(userId, applicationKey, basePath);
84+
this.basePath = basePath;
7285
this.userId = userId;
7386
this.applicationKey = applicationKey;
74-
this.defaultHeaders = new HashMap<>();
75-
this.httpRequestFactory = this.createRequestFactory();
7687
this.objectMapper = createDefaultObjectMapper();
7788
}
7889

79-
public HttpRequestFactory getHttpRequestFactory() {
80-
return httpRequestFactory;
90+
/**
91+
* Sets up the proxy properties for the API client.
92+
*/
93+
private void initializeProxyProperties(String proxyHostname, int proxyPort) {
94+
this.proxyHostname = proxyHostname;
95+
this.proxyPort = proxyPort;
8196
}
8297

83-
public HttpRequestFactory createRequestFactory() {
98+
/**
99+
* Constructs an ApiClient with the default base path.
100+
*/
101+
public ApiClient(long userId, String applicationKey) {
102+
this(userId, applicationKey, DEFAULT_BASE_PATH);
103+
}
104+
105+
/**
106+
* Constructs an ApiClient with a custom base path.
107+
*/
108+
public ApiClient(long userId, String applicationKey, String basePath) {
109+
initializeBaseProperties(userId, applicationKey, basePath);
110+
this.httpRequestFactory = createRequestFactory();
111+
}
112+
113+
/**
114+
* Constructor for ApiClient specifying user credentials, proxy details, and base path.
115+
*
116+
* @param userId user identifier for authentication.
117+
* @param applicationKey unique application key for user authentication.
118+
* @param basePath the base URL for API requests.
119+
* @param proxyHostname the hostname of the proxy server.
120+
* @param proxyPort the port of the proxy server.
121+
*/
122+
public ApiClient(long userId, String applicationKey, String basePath, String proxyHostname, int proxyPort) {
123+
initializeBaseProperties(userId, applicationKey, basePath);
124+
initializeProxyProperties(proxyHostname, proxyPort);
125+
this.httpRequestFactory = createRequestFactory();
126+
}
127+
128+
/**
129+
* Constructor for ApiClient specifying user credentials with the default base path and proxy details.
130+
*
131+
* @param userId user identifier for authentication.
132+
* @param applicationKey unique application key for user authentication.
133+
* @param proxyHostname the hostname of the proxy server.
134+
* @param proxyPort the port of the proxy server.
135+
*/
136+
public ApiClient(long userId, String applicationKey, String proxyHostname, int proxyPort) {
137+
this(userId, applicationKey, DEFAULT_BASE_PATH, proxyHostname, proxyPort);
138+
}
139+
140+
/**
141+
* Creates an HttpRequestFactory configured for making HTTP requests. The method initializes a transport builder
142+
* and potentially sets a proxy for it.
143+
*
144+
* @return HttpRequestFactory This factory is configured with the built transport and the interceptor.
145+
* It is ready for making HTTP requests, handling the details of connection
146+
* and protocol, allowing for high configurability and ease of modifications.
147+
*/
148+
private HttpRequestFactory createRequestFactory() {
84149
final RequestInterceptor interceptor = new RequestInterceptor(this.userId, this.applicationKey, this.defaultHeaders);
85-
NetHttpTransport transport = new NetHttpTransport();
86-
return transport.createRequestFactory(new HttpRequestInitializer() {
87-
public void initialize(HttpRequest request) {
88-
request.setInterceptor(interceptor);
89-
}
90-
});
150+
NetHttpTransport.Builder builder = new NetHttpTransport.Builder();
151+
152+
if (proxyHostname != null && !proxyHostname.isEmpty()) {
153+
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHostname, proxyPort));
154+
builder.setProxy(proxy);
155+
}
156+
157+
NetHttpTransport transport = builder.build();
158+
159+
return transport.createRequestFactory(request -> request.setInterceptor(interceptor));
91160
}
92161

162+
/**
163+
* Allows the addition of default headers that will be sent with each request.
164+
*/
93165
public void addDefaultHeader (String key, String value) {
94166
this.defaultHeaders.put(key, value);
95167
}
96168

169+
// Standard getters and setters
170+
public HttpRequestFactory getHttpRequestFactory() {
171+
return httpRequestFactory;
172+
}
173+
97174
public String getBasePath() {
98175
return basePath;
99176
}

src/main/java/ch/postfinance/sdk/DefaultHeaders.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void intercept(HttpRequest request) throws IOException {
3434

3535
private HttpHeaders getDefaultHeaders() {
3636
HttpHeaders headers = new HttpHeaders();
37-
headers.put("x-meta-sdk-version", "6.2.0");
37+
headers.put("x-meta-sdk-version", "7.0.0");
3838
headers.put("x-meta-sdk-language", "java");
3939
headers.put("x-meta-sdk-provider", "PostFinance Checkout");
4040
headers.put("x-meta-sdk-language-version", System.getProperty("java.version"));

0 commit comments

Comments
 (0)