Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update azure service proxy configuration #24810

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import com.azure.spring.cloud.autoconfigure.properties.AbstractAzureServiceConfigurationProperties;
import com.azure.spring.core.properties.client.ClientProperties;
import com.azure.spring.service.cosmos.CosmosProperties;
import com.azure.spring.core.properties.proxy.HttpProxyProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotEmpty;
Expand All @@ -27,6 +29,9 @@ public class AzureCosmosProperties extends AbstractAzureServiceConfigurationProp

public static final String PREFIX = "spring.cloud.azure.cosmos";

@NestedConfigurationProperty
private final HttpProxyProperties proxy = new HttpProxyProperties();

@NotEmpty
@Pattern(regexp = "http[s]{0,1}://.*.documents.azure.com.*")
private String endpoint;
Expand Down Expand Up @@ -64,6 +69,10 @@ public class AzureCosmosProperties extends AbstractAzureServiceConfigurationProp
*/
private boolean populateQueryMetrics;

@Override
public HttpProxyProperties getProxy() {
return proxy;
}

@Override
public ClientProperties getClient() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

package com.azure.spring.cloud.autoconfigure.properties;

import com.azure.spring.core.properties.proxy.ProxyProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;

/**
Expand All @@ -13,8 +14,16 @@ public abstract class AbstractAzureAmqpConfigurationProperties extends AbstractA
@NestedConfigurationProperty
protected final AmqpClientConfigurationProperties client = new AmqpClientConfigurationProperties();

@NestedConfigurationProperty
protected final ProxyProperties proxy = new ProxyProperties();

@Override
public AmqpClientConfigurationProperties getClient() {
return client;
}

@Override
public ProxyProperties getProxy() {
return proxy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

package com.azure.spring.cloud.autoconfigure.properties;

import com.azure.spring.core.properties.proxy.HttpProxyProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;

/**
Expand All @@ -13,8 +14,16 @@ public abstract class AbstractAzureHttpConfigurationProperties extends AbstractA
@NestedConfigurationProperty
protected final HttpClientConfigurationProperties client = new HttpClientConfigurationProperties();

@NestedConfigurationProperty
protected final HttpProxyProperties proxy = new HttpProxyProperties();

@Override
public HttpClientConfigurationProperties getClient() {
return client;
}

@Override
public HttpProxyProperties getProxy() {
return proxy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.azure.spring.core.properties.AzureProperties;
import com.azure.spring.core.properties.credential.TokenCredentialProperties;
import com.azure.spring.core.properties.profile.AzureProfile;
import com.azure.spring.core.properties.proxy.ProxyProperties;
import com.azure.spring.core.properties.resource.AzureResourceMetadata;
import com.azure.spring.core.properties.retry.RetryProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
Expand All @@ -18,9 +17,6 @@ public abstract class AbstractAzureServiceConfigurationProperties implements Azu

protected boolean enabled = true;

@NestedConfigurationProperty
protected final ProxyProperties proxy = new ProxyProperties();

@NestedConfigurationProperty
protected final RetryProperties retry = new RetryProperties();

Expand All @@ -41,11 +37,6 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

@Override
public ProxyProperties getProxy() {
return proxy;
}

@Override
public RetryProperties getRetry() {
return retry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
package com.azure.spring.core.converter;

import com.azure.core.http.ProxyOptions;
import com.azure.spring.core.properties.proxy.ProxyProperties;
import com.azure.spring.core.properties.proxy.HttpProxyProperties;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

import java.net.InetSocketAddress;

/**
* Converts a {@link ProxyProperties} to a {@link ProxyOptions}.
* Converts a {@link HttpProxyProperties} to a {@link ProxyOptions}.
*/
public final class AzureHttpProxyOptionsConverter implements Converter<ProxyProperties, ProxyOptions> {
public final class AzureHttpProxyOptionsConverter implements Converter<HttpProxyProperties, ProxyOptions> {

@Override
public ProxyOptions convert(ProxyProperties proxyProperties) {
public ProxyOptions convert(HttpProxyProperties proxyProperties) {
if (!StringUtils.hasText(proxyProperties.getHostname())) {
return null;
}
Expand All @@ -34,8 +34,9 @@ public ProxyOptions convert(ProxyProperties proxyProperties) {
if (StringUtils.hasText(proxyProperties.getUsername()) && StringUtils.hasText(proxyProperties.getPassword())) {
proxyOptions.setCredentials(proxyProperties.getUsername(), proxyProperties.getPassword());
}
// TODO (xiada) non proxy hosts
if (StringUtils.hasText(proxyProperties.getNonProxyHosts())) {
proxyOptions.setNonProxyHosts(proxyProperties.getNonProxyHosts());
}
return proxyOptions;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import com.azure.spring.core.properties.client.AmqpClientProperties;
import com.azure.spring.core.properties.client.ClientProperties;
import com.azure.spring.core.properties.retry.RetryProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.BiConsumer;

Expand All @@ -22,6 +24,7 @@
*/
public abstract class AbstractAzureAmqpClientBuilderFactory<T> extends AbstractAzureServiceClientBuilderFactory<T> {

private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAzureAmqpClientBuilderFactory.class);
private ClientOptions clientOptions = new ClientOptions();
private final AzureAmqpProxyOptionsConverter proxyOptionsConverter = new AzureAmqpProxyOptionsConverter();
private final AzureAmqpRetryOptionsConverter retryOptionsConverter = new AzureAmqpRetryOptionsConverter();
Expand Down Expand Up @@ -78,8 +81,13 @@ protected void configureProxy(T builder) {
if (getAzureProperties().getProxy() == null) {
return;
}

final ProxyOptions proxyOptions = proxyOptionsConverter.convert(getAzureProperties().getProxy());
consumeProxyOptions().accept(builder, proxyOptions);
if (proxyOptions != null) {
consumeProxyOptions().accept(builder, proxyOptions);
} else {
LOGGER.debug("No AMQP proxy properties available.");
}
}

protected ClientOptions getClientOptions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.azure.core.http.HttpClient;
import com.azure.core.http.HttpClientProvider;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.ProxyOptions;
import com.azure.core.http.policy.HttpLogOptions;
import com.azure.core.http.policy.HttpPipelinePolicy;
import com.azure.core.util.Header;
Expand All @@ -15,7 +16,10 @@
import com.azure.spring.core.http.DefaultHttpProvider;
import com.azure.spring.core.properties.client.ClientProperties;
import com.azure.spring.core.properties.client.HttpClientProperties;
import com.azure.spring.core.properties.proxy.HttpProxyProperties;
import com.azure.spring.core.properties.proxy.ProxyProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -30,6 +34,7 @@
*/
public abstract class AbstractAzureHttpClientBuilderFactory<T> extends AbstractAzureServiceClientBuilderFactory<T> {

private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAzureHttpClientBuilderFactory.class);
private final HttpClientOptions httpClientOptions = new HttpClientOptions();
private HttpClientProvider httpClientProvider = new DefaultHttpProvider();
private final List<HttpPipelinePolicy> httpPipelinePolicies = new ArrayList<>();
Expand Down Expand Up @@ -66,9 +71,20 @@ protected void configureHttpClient(T builder) {

@Override
protected void configureProxy(T builder) {
final ProxyProperties proxy = getAzureProperties().getProxy();
if (proxy != null) {
this.httpClientOptions.setProxyOptions(proxyOptionsConverter.convert(proxy));
final ProxyProperties proxyProperties = getAzureProperties().getProxy();
if (proxyProperties == null) {
return;
}

if (proxyProperties instanceof HttpProxyProperties) {
ProxyOptions proxyOptions = proxyOptionsConverter.convert((HttpProxyProperties) proxyProperties);
if (proxyOptions != null) {
this.httpClientOptions.setProxyOptions(proxyOptions);
} else {
LOGGER.debug("No HTTP proxy properties available.");
}
} else {
LOGGER.warn("Non-http proxy configuration will not be applied.");
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.core.properties.proxy;

/**
* Extend the proxy properties for HTTP connection
*/
public class HttpProxyProperties extends ProxyProperties {
private String nonProxyHosts;

public String getNonProxyHosts() {
return nonProxyHosts;
}

public void setNonProxyHosts(String nonProxyHosts) {
this.nonProxyHosts = nonProxyHosts;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,10 @@ protected void configureService(CosmosClientBuilder builder) {
// TODO (xiada): should we count this as authentication
map.from(this.cosmosProperties.getResourceToken()).to(builder::resourceToken);
map.from(this.cosmosProperties.getPermissions()).whenNot(List::isEmpty).to(builder::permissions);

if (ConnectionMode.GATEWAY.equals(this.cosmosProperties.getConnectionMode())) {
if (ConnectionMode.DIRECT.equals(this.cosmosProperties.getConnectionMode())) {
builder.directMode(this.cosmosProperties.getDirectConnection(), this.cosmosProperties.getGatewayConnection());
} else if (ConnectionMode.GATEWAY.equals(this.cosmosProperties.getConnectionMode())) {
builder.gatewayMode(this.cosmosProperties.getGatewayConnection());
} else if (ConnectionMode.DIRECT.equals(this.cosmosProperties.getConnectionMode())) {
// TODO (xiada): public CosmosClientBuilder directMode(DirectConnectionConfig directConnectionConfig, GatewayConnectionConfig gatewayConnectionConfig) {
builder.directMode(this.cosmosProperties.getDirectConnection());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.service.cosmos;

import com.azure.cosmos.ConnectionMode;
import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.DirectConnectionConfig;
import com.azure.cosmos.GatewayConnectionConfig;
import com.azure.spring.service.AzureServiceClientBuilderFactoryTestBase;
import org.junit.jupiter.api.Test;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.mock;

public class CosmosClientBuilderFactoryTest extends AzureServiceClientBuilderFactoryTestBase<CosmosClientBuilder,
TestAzureCosmosProperties, CosmosClientBuilderFactory> {

private static final String ENDPOINT = "https://test.documents.azure.com:443/";

@Test
void testGatewayConnectionModeConfigured() {
TestAzureCosmosProperties properties = createMinimalServiceProperties();
properties.setConnectionMode(ConnectionMode.GATEWAY);
final CosmosClientBuilderFactoryExt factoryExt = new CosmosClientBuilderFactoryExt(properties);
final CosmosClientBuilder builder = factoryExt.build();
verify(builder, times(1)).gatewayMode(any(GatewayConnectionConfig.class));
verify(builder, times(0)).directMode(any(DirectConnectionConfig.class));
}

@Test
void testDirectConnectionModeConfigured() {
TestAzureCosmosProperties properties = createMinimalServiceProperties();
properties.setConnectionMode(ConnectionMode.DIRECT);
final CosmosClientBuilderFactoryExt factoryExt = new CosmosClientBuilderFactoryExt(properties);
final CosmosClientBuilder builder = factoryExt.build();
verify(builder, times(0)).gatewayMode(any(GatewayConnectionConfig.class));
verify(builder, times(1)).directMode(any(DirectConnectionConfig.class), any(GatewayConnectionConfig.class));
}

@Override
protected TestAzureCosmosProperties createMinimalServiceProperties() {
TestAzureCosmosProperties cosmosProperties = new TestAzureCosmosProperties();
cosmosProperties.setEndpoint(ENDPOINT);
return cosmosProperties;
}

static class CosmosClientBuilderFactoryExt extends CosmosClientBuilderFactory {

CosmosClientBuilderFactoryExt(TestAzureCosmosProperties cosmosProperties) {
super(cosmosProperties);
}

@Override
protected CosmosClientBuilder createBuilderInstance() {
return mock(CosmosClientBuilder.class);
}
}
}
Loading