Skip to content

Commit

Permalink
Proxy refactor step 2 (#1295)
Browse files Browse the repository at this point in the history
* 1. rename MavenAuthUtils to MavenAuthManager
2. hide AzureAuthManager from public access(use MavenAuthManager instead)
3. tune the code for determine default subscription

Co-authored-by: Andy Xu(devdiv) <andxu@microsoft>
  • Loading branch information
andxu and Andy Xu(devdiv) authored Feb 4, 2021
1 parent da9a452 commit 584addb
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import com.microsoft.azure.maven.telemetry.TelemetryConfiguration;
import com.microsoft.azure.maven.telemetry.TelemetryProxy;
import com.microsoft.azure.maven.utils.CustomTextIoStringListReader;
import com.microsoft.azure.maven.utils.MavenAuthUtils;
import com.microsoft.azure.maven.auth.MavenAuthManager;
import com.microsoft.azure.maven.utils.MavenUtils;
import com.microsoft.azure.maven.utils.ProxyUtils;
import com.microsoft.azure.maven.utils.SystemPropertyUtils;
import com.microsoft.azure.toolkit.lib.common.proxy.ProxyManager;
import com.microsoft.azure.tools.auth.util.AzureEnvironmentUtils;
import com.microsoft.azure.tools.auth.exception.AzureLoginException;
import com.microsoft.azure.tools.auth.model.AzureCredentialWrapper;
Expand Down Expand Up @@ -310,7 +310,7 @@ protected String getAuthType() {
return StringUtils.firstNonBlank(auth == null ? null : auth.getType(), authType);
}

protected String selectSubscription(Azure az, Subscription[] subscriptions) throws AzureExecutionException {
protected String selectSubscription(Subscription[] subscriptions) throws AzureExecutionException {
if (subscriptions.length == 0) {
throw new AzureExecutionException("Cannot find any subscriptions in current account.");
}
Expand All @@ -319,12 +319,10 @@ protected String selectSubscription(Azure az, Subscription[] subscriptions) thro
TextUtils.blue(SubscriptionOption.getSubscriptionName(subscriptions[0]))));
return subscriptions[0].subscriptionId();
}
final String defaultId = Optional.ofNullable(az.getCurrentSubscription()).map(Subscription::subscriptionId).orElse(null);
final List<SubscriptionOption> wrapSubs = Arrays.stream(subscriptions).map(t -> new SubscriptionOption(t))
.sorted()
.collect(Collectors.toList());
final SubscriptionOption defaultValue = wrapSubs.stream()
.filter(t -> StringUtils.equalsIgnoreCase(t.getSubscriptionId(), defaultId)).findFirst().orElse(null);
final SubscriptionOption defaultValue = wrapSubs.get(0);
final TextIO textIO = TextIoFactory.getTextIO();
final SubscriptionOption subscriptionOptionSelected = new CustomTextIoStringListReader<SubscriptionOption>(() -> textIO.getTextTerminal(), null)
.withCustomPrompt(String.format("Please choose a subscription%s: ",
Expand All @@ -342,7 +340,7 @@ protected Azure getOrCreateAzureClient() throws AzureAuthFailureException, Azure
mavenAuthConfiguration.setType(getAuthType());

SystemPropertyUtils.injectCommandLineParameter("auth", mavenAuthConfiguration, MavenAuthConfiguration.class);
azureCredentialWrapper = MavenAuthUtils.login(session, settingsDecrypter, mavenAuthConfiguration);
azureCredentialWrapper = MavenAuthManager.getInstance().login(session, settingsDecrypter, mavenAuthConfiguration);

if (Objects.isNull(azureCredentialWrapper)) {
return null;
Expand All @@ -354,11 +352,10 @@ protected Azure getOrCreateAzureClient() throws AzureAuthFailureException, Azure
Log.prompt(String.format(USING_AZURE_ENVIRONMENT, TextUtils.cyan(environmentName)));
}
Log.info(azureCredentialWrapper.getCredentialDescription());
final Azure tempAzure = Azure.configure()
.authenticate(azureCredentialWrapper.getAzureTokenCredentials()).withDefaultSubscription();
final PagedList<Subscription> subscriptions = tempAzure.subscriptions().list();
final PagedList<Subscription> subscriptions = Azure.configure()
.authenticate(azureCredentialWrapper.getAzureTokenCredentials()).subscriptions().list();
subscriptions.loadAll();
final String targetSubscriptionId = getTargetSubscriptionId(tempAzure, subscriptions);
final String targetSubscriptionId = getTargetSubscriptionId(getSubscriptionId(), subscriptions);
checkSubscription(subscriptions, targetSubscriptionId);
azureCredentialWrapper.withDefaultSubscriptionId(targetSubscriptionId);
return AzureClientFactory.getAzureClient(azureCredentialWrapper, getUserAgent());
Expand Down Expand Up @@ -445,7 +442,7 @@ public String getAuthMethod() {
public void execute() throws MojoExecutionException {
try {
// init proxy manager
ProxyManager.getInstance().init();
ProxyUtils.initProxy(Optional.ofNullable(this.session).map(s -> s.getRequest()).orElse(null));

// Work around for Application Insights Java SDK:
// Sometimes, NoClassDefFoundError will be thrown even after Maven build is completed successfully.
Expand Down Expand Up @@ -619,9 +616,9 @@ protected interface RunnableWithException {
}
//endregion

private String getTargetSubscriptionId(Azure azure2, PagedList<Subscription> subscriptions) throws IOException, AzureExecutionException {
private String getTargetSubscriptionId(String defaultSubscriptionId, PagedList<Subscription> subscriptions) throws IOException, AzureExecutionException {
final List<String> subsIdList = subscriptions.stream().map(Subscription::subscriptionId).collect(Collectors.toList());
String targetSubscriptionId = StringUtils.firstNonBlank(this.subscriptionId, azureCredentialWrapper.getDefaultSubscriptionId());
String targetSubscriptionId = defaultSubscriptionId;

if (StringUtils.isBlank(targetSubscriptionId) && ArrayUtils.isNotEmpty(azureCredentialWrapper.getFilteredSubscriptionIds())) {
final Collection<String> filteredSubscriptions = StringListUtils.intersectIgnoreCase(subsIdList,
Expand All @@ -632,7 +629,7 @@ private String getTargetSubscriptionId(Azure azure2, PagedList<Subscription> sub
}

if (StringUtils.isBlank(targetSubscriptionId)) {
return selectSubscription(azure2, subscriptions.toArray(new Subscription[0]));
return selectSubscription(subscriptions.toArray(new Subscription[0]));
}
return targetSubscriptionId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* license information.
*/

package com.microsoft.azure.maven.utils;
package com.microsoft.azure.maven.auth;

import com.microsoft.azure.common.exceptions.AzureExecutionException;
import com.microsoft.azure.maven.exception.MavenDecryptException;
Expand All @@ -25,11 +25,17 @@

import static com.microsoft.azure.maven.auth.MavenSettingHelper.buildAuthConfigurationByServerId;

public class MavenAuthUtils {
public class MavenAuthManager extends AzureAuthManager {
private static final String INVALID_AZURE_ENVIRONMENT = "Invalid environment string '%s', please replace it with one of " +
"\"Azure\", \"AzureChina\", \"AzureGermany\", \"AzureUSGovernment\",.";
"\"Azure\", \"AzureChina\", \"AzureGermany\", \"AzureUSGovernment\",.";

public static AzureCredentialWrapper login(MavenSession session, SettingsDecrypter settingsDecrypter, @Nonnull MavenAuthConfiguration auth)
private static MavenAuthManager mavenAuthManager = new MavenAuthManager();

public static MavenAuthManager getInstance() {
return mavenAuthManager;
}

public AzureCredentialWrapper login(MavenSession session, SettingsDecrypter settingsDecrypter, @Nonnull MavenAuthConfiguration auth)
throws AzureExecutionException, MavenDecryptException, InvalidConfigurationException {
final String serverId = auth.getServerId();
final AuthConfiguration authConfiguration;
Expand All @@ -41,8 +47,7 @@ public static AzureCredentialWrapper login(MavenSession session, SettingsDecrypt
: "in <auth> configuration.";
throw new AzureExecutionException(String.format("%s %s", ex.getMessage(), messagePostfix));
}
ProxyUtils.configureProxy(session.getRequest());
return AzureAuthManager.getAzureCredentialWrapper(authConfiguration).toBlocking().value();
return super.login(authConfiguration).toBlocking().value();
}

private static AuthConfiguration convertToAuthConfiguration(MavenAuthConfiguration mavenAuthConfiguration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
import java.util.Objects;

public class ProxyUtils {
public static void configureProxy(MavenExecutionRequest request) {
public static void initProxy(MavenExecutionRequest request) {
final ProxyManager proxyManager = ProxyManager.getInstance();
proxyManager.init();
String source = "system";
if (Objects.isNull(proxyManager.getProxy())) {
if (!proxyManager.forceUseSystemProxy() && request != null) {
final List<Proxy> mavenProxies = request.getProxies();
if (CollectionUtils.isNotEmpty(mavenProxies)) {
final Proxy mavenProxy = mavenProxies.stream().filter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
import com.microsoft.azure.maven.springcloud.config.ConfigurationParser;
import com.microsoft.azure.maven.telemetry.AppInsightHelper;
import com.microsoft.azure.maven.telemetry.MojoStatus;
import com.microsoft.azure.maven.utils.MavenAuthUtils;
import com.microsoft.azure.toolkit.lib.common.proxy.ProxyManager;
import com.microsoft.azure.maven.auth.MavenAuthManager;
import com.microsoft.azure.maven.utils.ProxyUtils;
import com.microsoft.azure.tools.auth.util.AzureEnvironmentUtils;
import com.microsoft.azure.tools.auth.model.AzureCredentialWrapper;
import com.microsoft.azure.tools.exception.InvalidConfigurationException;
Expand All @@ -40,6 +40,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static com.microsoft.azure.maven.springcloud.TelemetryConstants.TELEMETRY_KEY_AUTH_METHOD;
import static com.microsoft.azure.maven.springcloud.TelemetryConstants.TELEMETRY_KEY_CPU;
Expand Down Expand Up @@ -149,13 +150,13 @@ public void execute() throws MojoFailureException {
protected void initExecution() throws MojoFailureException, MavenDecryptException, AzureExecutionException,
com.microsoft.azure.tools.auth.exception.InvalidConfigurationException {
// init proxy manager
ProxyManager.getInstance().init();
ProxyUtils.initProxy(Optional.ofNullable(this.session).map(s -> s.getRequest()).orElse(null));
// Init telemetries
initTelemetry();
trackMojoExecution(MojoStatus.Start);
final MavenAuthConfiguration mavenAuthConfiguration = auth == null ? new MavenAuthConfiguration() : auth;
mavenAuthConfiguration.setType(getAuthType());
this.azureCredentialWrapper = MavenAuthUtils.login(session, settingsDecrypter, mavenAuthConfiguration);
this.azureCredentialWrapper = MavenAuthManager.getInstance().login(session, settingsDecrypter, mavenAuthConfiguration);
if (Objects.isNull(azureCredentialWrapper)) {
AppInsightHelper.INSTANCE.trackEvent(INIT_FAILURE);
throw new MojoFailureException(AZURE_INIT_FAIL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import java.util.Map;

public class AzureAuthManager {
public static Single<AzureCredentialWrapper> getAzureCredentialWrapper(AuthConfiguration configuration) {
protected Single<AzureCredentialWrapper> login(AuthConfiguration configuration) {
AuthConfiguration auth = MoreObjects.firstNonNull(configuration, new AuthConfiguration());
AzureEnvironmentUtils.setupAzureEnvironment(auth.getEnvironment());
ChainedCredentialRetriever chainedCredentialRetriever = new ChainedCredentialRetriever();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for
* license information.
Expand All @@ -9,7 +9,6 @@
import com.google.common.base.Preconditions;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;

import javax.annotation.Nonnull;

Expand All @@ -29,7 +28,9 @@
public class ProxyManager {
private static final String PROPERTY_USE_SYSTEM_PROXY = "java.net.useSystemProxies";
private static final int MAX_PORT_NUMBER = 65535;

// isSystemProxyUnset shows whether user specify the proxy through -Djava.net.useSystemProxies
// see: https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
private static final boolean isSystemProxyUnset = StringUtils.isBlank(System.getProperty(PROPERTY_USE_SYSTEM_PROXY));
@Getter
private Proxy proxy;

Expand All @@ -43,15 +44,15 @@ public static ProxyManager getInstance() {

public String getHttpProxyHost() {
if (Objects.nonNull(this.proxy) && proxy.address() instanceof InetSocketAddress) {
InetSocketAddress address = (InetSocketAddress) proxy.address();
final InetSocketAddress address = (InetSocketAddress) proxy.address();
return address.getHostString();
}
return null;
}

public int getHttpProxyPort() {
if (Objects.nonNull(this.proxy) && proxy.address() instanceof InetSocketAddress) {
InetSocketAddress address = (InetSocketAddress) proxy.address();
final InetSocketAddress address = (InetSocketAddress) proxy.address();
return address.getPort();
}
return 0;
Expand All @@ -64,32 +65,40 @@ public void configure(@Nonnull String httpProxyHost, @Nonnull Integer httpProxyP
throw new IllegalArgumentException(
String.format("Invalid range of httpProxyPort: '%s', it should be a number between %d and %d", httpProxyPort, 1, MAX_PORT_NUMBER));
}
// proxy conflicting
if (forceUseSystemProxy()) {
throw new IllegalArgumentException("Cannot set the proxy second time when user has specified the proxy through " +
"vm arguments: -Djava.net.useSystemProxies=true.");
}
this.proxy = createHttpProxy(httpProxyHost, httpProxyPort);
replaceDefaultProxySelector();
}

public void init() {
// if user wants to use or not use system proxy explicitly
Proxy systemProxy = getSystemProxy();
if (systemProxy != null) {
this.proxy = systemProxy;
// we need to init at the program start before any internet access
if (isSystemProxyUnset) {
// to make ProxySelector return the system proxy, we need to set java.net.useSystemProxies = true
System.setProperty(PROPERTY_USE_SYSTEM_PROXY, "true");
}
this.proxy = getSystemProxyInner();
if (isSystemProxyUnset) {
System.clearProperty(PROPERTY_USE_SYSTEM_PROXY);
}
this.replaceSystemProxySelector();
}

private void replaceSystemProxySelector() {
final ProxySelector ds = ProxySelector.getDefault();
public boolean forceUseSystemProxy() {
return !isSystemProxyUnset && this.proxy != null;
}

private void replaceDefaultProxySelector() {
ProxySelector.setDefault(new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
if (Objects.nonNull(ProxyManager.this.proxy)) {
return Collections.singletonList(ProxyManager.this.proxy);
}
return ds.select(uri);
return Collections.singletonList(ProxyManager.this.proxy);
}

@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
ds.connectFailed(uri, sa, ioe);
}
});
}
Expand All @@ -99,26 +108,6 @@ private static Proxy createHttpProxy(String httpProxyHost, Integer httpProxyPort
httpProxyPort)) : null;
}

private static Proxy getSystemProxy() {
boolean isSystemProxyUnset = StringUtils.isBlank(System.getProperty(PROPERTY_USE_SYSTEM_PROXY));
try {
if (isSystemProxyUnset) {
System.setProperty(PROPERTY_USE_SYSTEM_PROXY, "true");
}
return getSystemProxyInner();
} finally {
try {
if (isSystemProxyUnset) {
// revert the influence of System.setProperty(PROPERTY_USE_SYSTEM_PROXY, "true")
FieldUtils.writeStaticField(ProxySelector.getDefault().getClass(), "hasSystemProxies", false, true);
System.clearProperty(PROPERTY_USE_SYSTEM_PROXY);
}
} catch (NullPointerException | IllegalAccessException ex) {
// ignore
}
}
}

@SneakyThrows
private static Proxy getSystemProxyInner() {
final URI uri = new URI("https://login.microsoft.com");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
import com.microsoft.azure.management.appservice.WebContainer;
import com.microsoft.azure.maven.AbstractAppServiceMojo;
import com.microsoft.azure.maven.auth.AzureAuthFailureException;
import com.microsoft.azure.maven.auth.MavenAuthManager;
import com.microsoft.azure.maven.model.MavenAuthConfiguration;
import com.microsoft.azure.maven.model.SubscriptionOption2;
import com.microsoft.azure.maven.utils.CustomTextIoStringListReader;
import com.microsoft.azure.maven.utils.MavenAuthUtils;
import com.microsoft.azure.maven.utils.SystemPropertyUtils;
import com.microsoft.azure.maven.webapp.configuration.ContainerSetting;
import com.microsoft.azure.maven.webapp.configuration.Deployment;
Expand Down Expand Up @@ -424,7 +424,7 @@ protected AzureAppService getOrCreateAzureAppServiceClient() throws AzureExecuti
try {
final MavenAuthConfiguration mavenAuthConfiguration = auth == null ? new MavenAuthConfiguration() : auth;
mavenAuthConfiguration.setType(getAuthType());
final AzureCredentialWrapper azureCredentialWrapper = MavenAuthUtils.login(session, settingsDecrypter, mavenAuthConfiguration);
final AzureCredentialWrapper azureCredentialWrapper = MavenAuthManager.getInstance().login(session, settingsDecrypter, mavenAuthConfiguration);
if (Objects.isNull(azureCredentialWrapper)) {
return null;
}
Expand Down

0 comments on commit 584addb

Please sign in to comment.