Skip to content

Commit af1f7a2

Browse files
authored
Merge pull request #73 from oracle/release_2018-08-09
Releasing version 1.2.44
2 parents 889eda6 + c2a85c9 commit af1f7a2

File tree

40 files changed

+930
-110
lines changed

40 files changed

+930
-110
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
1313
### Added
1414
- N/A
1515

16+
## 1.2.44 - 2018-08-09
17+
### Added
18+
- Support for fault domains in the Compute service
19+
- Support for configuring a connection pool and an HTTP(S) proxy with the apache connector add-on. More information is available [here](http://github.com/oracle/oci-java-sdk/blob/master/bmc-addons/bmc-apache-connector-provider/README.md)
20+
1621
## 1.2.43 - 2018-07-26
1722
### Added
1823
- Support for the OCI Search service. An example of how to call this service is available [here](https://github.com/oracle/oci-java-sdk/blob/master/bmc-examples/src/main/java/ResourceSearchExample.java)
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# OCI Java SDK Apache Connector Add-On
2+
3+
## About
4+
5+
The oci-java-sdk-addons-apache is an optional add-on to the OCI Java SDK. It leverages the Jersey `ApacheConnectorProvider` instead of the OCI Java SDK's default `HttpUrlConnectorProvider` when making service calls.
6+
7+
The add-on provides two features:
8+
9+
* **Connection pooling**. A detailed explantation can be found [here](https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html)
10+
* **HTTP(S) proxy support**.
11+
12+
Note: The `ApacheConnectorProvider` buffers requests into memory and can impact memory utilization of your application. This increased use of memory is especially relavent when using`ObjectStorageClient` to upload large objects to the Object Storage service.
13+
14+
## Installation
15+
1. The OCI Java SDK must be installed and configured before installing the add-on. See [the documentation](https://docs.us-phoenix-1.oraclecloud.com/Content/API/SDKDocs/javasdk.htm) for details.
16+
2. Copy the supplied oci-java-sdk-addons-apache and third-party jar files to your application's classpath.
17+
18+
## Configuration
19+
20+
Create a client with the ```ApacheConfigurator```:
21+
22+
IdentityClient identityClient = IdentityClient.builder()
23+
.region(Region.US_PHOENIX_1)
24+
.clientConfigurator(new ApacheConfigurator())
25+
.build(authenticationDetailsProvider);
26+
27+
### Configure the Connection Pool
28+
29+
Configure the connection pool as follows:
30+
31+
ApacheConnectionPoolConfig poolConfig = ApacheConnectionPoolConfig.builder()
32+
.defaultMaxConnectionsPerRoute(5)
33+
.totalOpenConnections(20)
34+
.ttl(2, TimeUnit.SECONDS)
35+
.build();
36+
ApacheConnectionPoolingClientConfigDecorator poolDecorator =
37+
new ApacheConnectionPoolingClientConfigDecorator(poolConfig);
38+
ApacheConfigurator configurator =
39+
new ApacheConfigurator(Collections.singletonList(poolDecorator));
40+
41+
IdentityClient identityClient = IdentityClient.builder()
42+
.region(Region.US_PHOENIX_1)
43+
.clientConfigurator(configurator)
44+
.build(authenticationDetailsProvider);
45+
46+
Documentation explaining the configuration concepts can be found [here](https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html).
47+
48+
### Configure the HTTP Proxy
49+
50+
This add-on supports configuring a client to use a HTTP or HTTPS proxy. It is configured configured on a per-client basis, meaning that a proxy must be configured for each new client instance.
51+
52+
Configure an HTTP or HTTPS proxy as follows:
53+
54+
#### Authenticated Proxy
55+
56+
ApacheProxyConfig proxyConfig = ApacheProxyConfig.builder()
57+
.uri("http://proxy.domain.com:8000")
58+
.username("username")
59+
.password("password")
60+
.build();
61+
ClientConfigDecorator proxyConfigDecorator =
62+
new ApacheProxyConfigDecorator(proxyConfig);
63+
ClientConfigurator configurator =
64+
new ApacheConfigurator(Collections.singletonList(proxyConfigDecorator));
65+
66+
IdentityClient identityClient = IdentityClient.builder()
67+
.region(Region.US_PHOENIX_1)
68+
.clientConfigurator(configurator)
69+
.build(authenticationDetailsProvider);
70+
71+
#### Unauthenticated Proxy
72+
73+
ApacheProxyConfig proxyConfig = ApacheProxyConfig.builder()
74+
.uri("https://proxy.domain.com:443")
75+
.build();
76+
ClientConfigDecorator proxyConfigDecorator =
77+
new ApacheProxyConfigDecorator(proxyConfig);
78+
ClientConfigurator configurator =
79+
new ApacheConfigurator(Collections.singletonList(proxyConfigDecorator));
80+
81+
IdentityClient identityClient = IdentityClient.builder()
82+
.region(Region.US_PHOENIX_1)
83+
.clientConfigurator(configurator)
84+
.build(authenticationDetailsProvider);
85+
86+
#### Example
87+
An example of configuring a proxy can be found [here](https://github.com/oracle/oci-java-sdk/tree/master/bmc-examples/src/main/java/HttpProxyExample.java).
88+
89+
90+
## License
91+
Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
92+
93+
This SDK and sample is dual licensed under the Universal Permissive License 1.0 and the Apache License 2.0.
94+
95+
See [LICENSE](../../LICENSE.txt) for more details.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>com.oracle.oci.sdk</groupId>
7+
<artifactId>oci-java-sdk-addons</artifactId>
8+
<version>1.2.44</version>
9+
<relativePath>../pom.xml</relativePath>
10+
</parent>
11+
12+
<artifactId>oci-java-sdk-addons-apache</artifactId>
13+
<name>Oracle Cloud Infrastructure SDK - ApacheHttpConenctorProvider</name>
14+
<description>This project adds support for the ApacheHttpConnectorProvider for the Java SDK</description>
15+
<url>https://docs.us-phoenix-1.oraclecloud.com/Content/API/SDKDocs/javasdk.htm</url>
16+
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.glassfish.jersey.core</groupId>
21+
<artifactId>jersey-client</artifactId>
22+
<version>${jersey.version}</version>
23+
</dependency>
24+
25+
<dependency>
26+
<groupId>org.glassfish.jersey.connectors</groupId>
27+
<artifactId>jersey-apache-connector</artifactId>
28+
<version>${jersey.version}</version>
29+
</dependency>
30+
31+
<dependency>
32+
<groupId>org.apache.commons</groupId>
33+
<artifactId>commons-lang3</artifactId>
34+
<version>${commons-lang3.version}</version>
35+
</dependency>
36+
37+
<dependency>
38+
<groupId>com.oracle.oci.sdk</groupId>
39+
<artifactId>oci-java-sdk-common</artifactId>
40+
<version>1.2.44</version>
41+
</dependency>
42+
</dependencies>
43+
</project>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
4+
5+
<id>release</id>
6+
<includeBaseDirectory>false</includeBaseDirectory>
7+
<formats>
8+
<format>zip</format>
9+
</formats>
10+
<fileSets>
11+
<!-- Include the README.md -->
12+
<fileSet>
13+
<directory>${project.basedir}</directory>
14+
<outputDirectory></outputDirectory>
15+
<includes>
16+
<include>README.md</include>
17+
</includes>
18+
</fileSet>
19+
<!-- Include all of the Javadocs -->
20+
<fileSet>
21+
<directory>${project.build.directory}/apidocs</directory>
22+
<outputDirectory>apidocs</outputDirectory>
23+
</fileSet>
24+
<!-- Include the sources and javadoc jars for developers -->
25+
<fileSet>
26+
<directory>${project.build.directory}</directory>
27+
<includes>
28+
<include>oci-java-sdk-addons-apache-${project.version}-*.jar</include>
29+
</includes>
30+
<outputDirectory>lib</outputDirectory>
31+
</fileSet>
32+
</fileSets>
33+
<files>
34+
<!-- Explicitly copy the signed/unsigned jar and rename it in the release zip file.
35+
If this is for a "signed" release, then the signed jar should be defined; else, the unsigned if the
36+
build profile is "ziponly" -->
37+
<file>
38+
<source>${source.jar.for.zip}</source>
39+
<outputDirectory>lib</outputDirectory>
40+
<destName>oci-java-sdk-addons-apache-${project.version}.jar</destName>
41+
</file>
42+
</files>
43+
<dependencySets>
44+
<!-- 3P dependencies only that's exclusive to this add-on, exclude OCI and its related third-party dependencies -->
45+
<dependencySet>
46+
<includes>
47+
<include>commons-logging:commons-logging</include>
48+
<include>org.glassfish.jersey.connectors:jersey-apache-connector</include>
49+
<include>org.apache.httpcomponents:*</include>
50+
</includes>
51+
<outputDirectory>third-party/lib</outputDirectory>
52+
<useProjectArtifact>false</useProjectArtifact>
53+
<useProjectAttachments>false</useProjectAttachments>
54+
<scope>runtime</scope>
55+
</dependencySet>
56+
</dependencySets>
57+
</assembly>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3+
*/
4+
package com.oracle.bmc.http;
5+
6+
import lombok.extern.slf4j.Slf4j;
7+
import org.apache.commons.lang3.StringUtils;
8+
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
9+
import org.glassfish.jersey.client.ClientConfig;
10+
import org.glassfish.jersey.client.ClientProperties;
11+
import org.glassfish.jersey.client.RequestEntityProcessing;
12+
13+
import javax.ws.rs.client.Client;
14+
import javax.ws.rs.client.ClientBuilder;
15+
import javax.ws.rs.client.ClientRequestContext;
16+
import javax.ws.rs.client.ClientRequestFilter;
17+
import java.util.LinkedList;
18+
import java.util.List;
19+
20+
/**
21+
* A {@code ClientConfigurator} implementation that uses the Apache HTTP Connector Provider for the Jersey Client
22+
* configuration. This enables support for connection pooling in addition to per-client HTTP(S) proxy support.
23+
*
24+
* Note: Use of the ApacheConnectorProvider will buffer requests into memory and can impact memory utilization within
25+
* your application.
26+
*/
27+
@Slf4j
28+
public class ApacheConfigurator implements ClientConfigurator {
29+
/** The list of {@code ClientConfigDecorator}s to support the ability to decorate {@code ClientConfig} */
30+
protected final List<ClientConfigDecorator> clientConfigDecorators = new LinkedList<>();
31+
32+
/** Creates a new {@code ApacheConfigurator} object. */
33+
public ApacheConfigurator() {}
34+
35+
/**
36+
* Creates a new {@code ApacheConfigurator} and registers the list of provided {@code ClientConfigDecorator}s.
37+
*
38+
* @param clientConfigDecorators the list of client configuration decorators
39+
*/
40+
public ApacheConfigurator(final List<ClientConfigDecorator> clientConfigDecorators) {
41+
this.clientConfigDecorators.addAll(clientConfigDecorators);
42+
}
43+
44+
@Override
45+
public void customizeBuilder(ClientBuilder builder) {
46+
setConnectorProvider(builder);
47+
}
48+
49+
@Override
50+
public void customizeClient(Client client) {
51+
// Use buffered processing to get better error messages on POST and PUT
52+
// but the downside is that this will buffer large uploads in memory.
53+
client.property(
54+
ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED);
55+
56+
// Required for calls to only allow Apache to set the content-length header.
57+
// Otherwise, apache will throw an exception if it already exists. For example, such a case includes
58+
// ObjectStorage where the content-length is explicitly set in the header based on the value in the request.
59+
client.register(new ContentLengthFilter());
60+
}
61+
62+
protected void setConnectorProvider(ClientBuilder builder) {
63+
LOG.info("Setting connector provider to ApacheConnectorProviders");
64+
65+
final ClientConfig clientConfig = new ClientConfig();
66+
clientConfig.connectorProvider(new ApacheConnectorProvider());
67+
68+
// Decorate config with any configured client config decorators
69+
for (ClientConfigDecorator clientConfigDecorator : clientConfigDecorators) {
70+
clientConfigDecorator.customizeClientConfig(clientConfig);
71+
}
72+
73+
builder.withConfig(clientConfig);
74+
}
75+
76+
private static class ContentLengthFilter implements ClientRequestFilter {
77+
@Override
78+
public void filter(ClientRequestContext requestContext) {
79+
String contentLengthHeader = null;
80+
for (String key : requestContext.getHeaders().keySet()) {
81+
if (StringUtils.equalsIgnoreCase("content-length", key)) {
82+
contentLengthHeader = key;
83+
}
84+
}
85+
86+
final String method = requestContext.getMethod();
87+
final String uri = requestContext.getUri().toString();
88+
final Object existingContentLengthValue =
89+
requestContext.getHeaders().remove(contentLengthHeader);
90+
if (existingContentLengthValue != null) {
91+
LOG.debug(
92+
"Removed existing content-length header for Method [{}], URI [{}], Existing Value [{}]",
93+
method,
94+
uri,
95+
existingContentLengthValue);
96+
} else {
97+
LOG.debug("content-length not found for Method [{}], URI [{}]", method, uri);
98+
}
99+
}
100+
}
101+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3+
*/
4+
package com.oracle.bmc.http;
5+
6+
import lombok.Data;
7+
import org.apache.commons.lang3.tuple.Pair;
8+
9+
import java.util.concurrent.TimeUnit;
10+
11+
/** The configurable parameters for a client's connection pool */
12+
@Data
13+
public class ApacheConnectionPoolConfig {
14+
/**
15+
* Creates a new default {@code ApacheConnectionPoolConfig}.
16+
*
17+
* @return a new default connection pool configuration
18+
*/
19+
public static ApacheConnectionPoolConfig newDefault() {
20+
return ApacheConnectionPoolConfig.builder()
21+
.defaultMaxConnectionsPerRoute(5)
22+
.totalOpenConnections(20)
23+
.build();
24+
}
25+
26+
/** Creates a new {@code Builder} used to construct a new {@code ApacheConnectionPoolConfig} object. **/
27+
public static Builder builder() {
28+
return new Builder();
29+
}
30+
31+
/** The max total number of connections. */
32+
private final int totalOpenConnections;
33+
/** The default max number of connections per route. */
34+
private final int defaultMaxConnectionsPerRoute;
35+
/** The time to live per connection. */
36+
private final Pair<Integer, TimeUnit> ttl;
37+
38+
private ApacheConnectionPoolConfig(final Builder builder) {
39+
totalOpenConnections = builder.totalOpenConnections;
40+
defaultMaxConnectionsPerRoute = builder.defaultMaxConnectionsPerRoute;
41+
ttl = builder.ttl;
42+
}
43+
44+
public final static class Builder {
45+
private int totalOpenConnections;
46+
private int defaultMaxConnectionsPerRoute;
47+
private Pair ttl;
48+
49+
public Builder() {}
50+
51+
public Builder totalOpenConnections(final int totalOpenConnections) {
52+
this.totalOpenConnections = totalOpenConnections;
53+
return this;
54+
}
55+
56+
public Builder defaultMaxConnectionsPerRoute(final int defaultMaxConnectionsPerRoute) {
57+
this.defaultMaxConnectionsPerRoute = defaultMaxConnectionsPerRoute;
58+
return this;
59+
}
60+
61+
public Builder ttlInMillis(final int ttlInMillis) {
62+
this.ttl = Pair.of(ttlInMillis, TimeUnit.MILLISECONDS);
63+
return this;
64+
}
65+
66+
public Builder ttl(final int ttl, final TimeUnit ttlTimeUnit) {
67+
this.ttl = Pair.of(ttl, ttlTimeUnit);
68+
return this;
69+
}
70+
71+
public ApacheConnectionPoolConfig build() {
72+
return new ApacheConnectionPoolConfig(this);
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)