Skip to content

Commit

Permalink
Fixed an issue with not loading functions when default profile does n…
Browse files Browse the repository at this point in the history
…ot exist. Extended logging messages.
  • Loading branch information
satr committed Sep 30, 2018
1 parent acdff50 commit 23b4144
Show file tree
Hide file tree
Showing 18 changed files with 831 additions and 538 deletions.
2 changes: 2 additions & 0 deletions sources/.idea/dictionaries/naveronics.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sources/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

813 changes: 455 additions & 358 deletions sources/.idea/workspace.xml

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion sources/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<idea-plugin>
<id>io.github.satr.idea.plugin.connector.la</id>
<name>Connector for AWS Lambda</name>
<version>1.7.RC2</version>
<version>1.7.RC3</version>
<vendor email="[email protected]" url="https://satr.github.io/intellij-idea-plugin-connector-for-aws-lambda/">github.com/satr</vendor>

<description><![CDATA[
Expand All @@ -14,6 +14,8 @@

<change-notes><![CDATA[
<ul>
<li>1.7.RC3</li>
<li>Fixed an issue with not loading functions when default profile does not exist.</li>
<li>1.7.RC2</li>
<li>Added basic support for uploading Node.js function with zip-archived artifact.</li>
<li>1.7.RC1</li>
Expand Down
9 changes: 5 additions & 4 deletions sources/src/io/github/satr/common/JsonHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ public class JsonHelper {
private final String RESULT_KEY = "result";

public OperationValueResult<String> Reformat(String jsonText) {
OperationValueResultImpl<String> valueResult = new OperationValueResultImpl<>();
OperationValueResultImpl<String> result = new OperationValueResultImpl<>();
scriptEngine.put(VALUE_FORMAT, jsonText);
try {
scriptEngine.eval(SCRIPT_PARAMS);
valueResult.setValue((String)scriptEngine.get(RESULT_KEY));
result.setValue((String)scriptEngine.get(RESULT_KEY));
} catch (ScriptException e) {
valueResult.addError(e.getMessage());
e.printStackTrace();
result.addError(e.getMessage());
}
return valueResult;
return result;
}
}
2 changes: 2 additions & 0 deletions sources/src/io/github/satr/common/OperationResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ public interface OperationResult {
void addInfo(String format, Object... args);
void addWarning(String format, Object... arg);
void addError(String format, Object... args);
void addDebug(String format, Object... args);
boolean failed();
boolean success();
boolean hasInfo();
boolean hasWarnings();
boolean hasErrors();
String getDebugAsString();
String getErrorAsString();
String getWarningsAsString();
String getInfoAsString();
Expand Down
11 changes: 11 additions & 0 deletions sources/src/io/github/satr/common/OperationResultImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.List;

public class OperationResultImpl implements OperationResult {
private final List<String> debugMessages = new ArrayList<>();
private final List<String> errorMessages = new ArrayList<>();
private final List<String> warningMessages = new ArrayList<>();
private final List<String> infoMessages = new ArrayList<>();
Expand All @@ -21,6 +22,11 @@ public void addError(String format, Object... args) {
errorMessages.add(String.format(format, args));
}

@Override
public void addDebug(String format, Object... args) {
debugMessages.add(String.format(format, args));
}

@Override
public void addWarning(String format, Object... args) {
warningMessages.add(String.format(format, args));
Expand Down Expand Up @@ -56,6 +62,11 @@ public String getErrorAsString() {
return join(errorMessages);
}

@Override
public String getDebugAsString() {
return join(debugMessages);
}

@Override
public String getWarningsAsString() {
return join(warningMessages);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public BasicProfile getBasicProfile() {
@Override
public String toString() {
String regionName = getBasicProfile().getRegion();
return String.format("%s (%s)", getName(), isEmpty(regionName) ? "no region" : regionName);
return String.format("%s (%s)", getName(), isEmpty(regionName) ? "no regionName" : regionName);
}
}
Original file line number Diff line number Diff line change
@@ -1,75 +1,187 @@
package io.github.satr.idea.plugin.connector.la.models;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.auth.profile.ProfilesConfigFile;
import com.amazonaws.auth.profile.internal.AllProfiles;
import com.amazonaws.auth.profile.internal.BasicProfile;
import com.amazonaws.auth.profile.internal.BasicProfileConfigLoader;
import com.amazonaws.auth.profile.internal.ProfileStaticCredentialsProvider;
import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
import com.amazonaws.regions.Regions;
import com.intellij.util.net.HttpConfigurable;
import io.github.satr.common.Logger;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.apache.http.util.TextUtils.isEmpty;

public abstract class AbstractConnectorModel {
protected final Regions region;
protected String regionName;
protected String proxyDetails = "Unknown";
protected String credentialProfileName;
private Logger logger;

public AbstractConnectorModel(Regions region, String credentialProfileName) {
this.region = region;
public AbstractConnectorModel(String regionName, String credentialProfileName, Logger logger) {
this.regionName = regionName;
this.credentialProfileName = credentialProfileName;
this.logger = logger;
}

protected Logger getLogger() {
return logger;
}

protected ClientConfiguration getClientConfiguration() {
HttpConfigurable httpConfigurable = HttpConfigurable.getInstance();
ClientConfiguration clientConfiguration = new ClientConfiguration();
boolean useProxyAuto = httpConfigurable.USE_PROXY_PAC;
if (useProxyAuto) {
proxyDetails = "Auto";
} else if (!httpConfigurable.USE_HTTP_PROXY) {
proxyDetails = "Not used";
try {
HttpConfigurable httpConfigurable = HttpConfigurable.getInstance();
ClientConfiguration clientConfiguration = new ClientConfiguration();
boolean useProxyAuto = httpConfigurable.USE_PROXY_PAC;
if (useProxyAuto) {
proxyDetails = "Auto";
} else if (!httpConfigurable.USE_HTTP_PROXY) {
proxyDetails = "Not used";
return clientConfiguration;
}
String proxyHost = httpConfigurable.PROXY_HOST;
int proxyPort = httpConfigurable.PROXY_PORT;
clientConfiguration = clientConfiguration.withProxyHost(proxyHost)
.withProxyPort(proxyPort);
if (!useProxyAuto) {
proxyDetails = String.format("%s:%s", proxyHost, proxyPort);
}

if (httpConfigurable.PROXY_AUTHENTICATION) {
String proxyLogin = httpConfigurable.getProxyLogin();
clientConfiguration = clientConfiguration.withProxyPassword(httpConfigurable.getPlainProxyPassword())
.withProxyUsername(proxyLogin);
}
return clientConfiguration;
} catch (Exception e) {
e.printStackTrace();
getLogger().logError("Getting od the client configuration failed: %s", e.getMessage());
}
String proxyHost = httpConfigurable.PROXY_HOST;
int proxyPort = httpConfigurable.PROXY_PORT;
clientConfiguration = clientConfiguration.withProxyHost(proxyHost)
.withProxyPort(proxyPort);
if (!useProxyAuto) {
proxyDetails = String.format("%s:%s", proxyHost, proxyPort);
return null;
}

protected AWSCredentialsProvider getCredentialsProvider() {
if (isEmpty(credentialProfileName)) {
getLogger().logDebug("Cannot get a profile for an empty name");
return tryDefaultAwsCredentialsProviderChain();
}
if (!validateCredentialProfilesExist()) {
getLogger().logError("Cannot find any credentials profiles. Please create at least one.");
return tryDefaultAwsCredentialsProviderChain();
}

if (httpConfigurable.PROXY_AUTHENTICATION) {
String proxyLogin = httpConfigurable.getProxyLogin();
clientConfiguration = clientConfiguration.withProxyPassword(httpConfigurable.getPlainProxyPassword())
.withProxyUsername(proxyLogin);
ProfileStaticCredentialsProvider profileCredentialsProvider = null;
AllProfiles allBasicProfiles = loadProfilesWithProperties();
BasicProfile profile = allBasicProfiles.getProfile(credentialProfileName);
if (profile == null) {
getLogger().logDebug("Last loaded profile does not exist: \"%s\".", credentialProfileName);
} else {
getLogger().logDebug("Select the profile \"%s\".", credentialProfileName);
profileCredentialsProvider = tryCreateProfileCredentialsProvider(profile);
if (profileCredentialsProvider != null) {
String profileRegionName = profile.getRegion();
if(!isEmpty(profileRegionName)) {
getLogger().logDebug("Selected a region from the profile: %s", regionName);
regionName = profileRegionName;
}
return profileCredentialsProvider;
}
}
profileCredentialsProvider = tryGetAlternativeAwsCredentialsProvider(credentialProfileName, allBasicProfiles);
if (profileCredentialsProvider != null) {
return profileCredentialsProvider;
}
return clientConfiguration;
getLogger().logDebug("No profiles could be selected and used.");
return tryDefaultAwsCredentialsProviderChain();
}

protected AWSCredentialsProvider getCredentialsProvider(String credentialProfileName) {
return validateCredentialProfile(credentialProfileName)
? new ProfileCredentialsProvider(credentialProfileName)
: DefaultAWSCredentialsProviderChain.getInstance();
@Nullable
private ProfileStaticCredentialsProvider tryGetAlternativeAwsCredentialsProvider(String skipProfileName, AllProfiles allBasicProfiles) {
ProfileStaticCredentialsProvider profileCredentialsProvider;
for(BasicProfile alternativeProfile : allBasicProfiles.getProfiles().values()) {
if(alternativeProfile.getProfileName().equals(skipProfileName)) {
continue; //skip the profile, already checked before
}
getLogger().logDebug("Try to selected the profile \"%s\".", alternativeProfile.getProfileName());
profileCredentialsProvider = tryCreateProfileCredentialsProvider(alternativeProfile);
if (profileCredentialsProvider != null) {
credentialProfileName = alternativeProfile.getProfileName();
String profileRegionName = alternativeProfile.getRegion();
if(!isEmpty(profileRegionName)) {
getLogger().logDebug("Selected a region from the profile: %s", regionName);
regionName = profileRegionName;
}
return profileCredentialsProvider;
}
}
return null;
}

private boolean validateCredentialProfile(String credentialProfileName) {
return !isEmpty(credentialProfileName)
&& validateCredentialProfilesExist()
&& new ProfilesConfigFile().getAllBasicProfiles().containsKey(credentialProfileName);
//Load profiles from the file ".aws/credentials" with regions and other properties (if exist) from the file ".aws/config"
//Logic has been borrowed from https://github.com/aws/aws-sdk-java/issues/803#issuecomment-374043898
//The issue with not loading regions from the file ".aws/config" supposed to be fixed in Java SDK 2.0, which is in "preview" now
//Java SDK 2.0 https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/welcome.html
private static AllProfiles loadProfilesWithProperties() {
final AllProfiles allProfiles = new AllProfiles(Stream.concat(
BasicProfileConfigLoader.INSTANCE.loadProfiles(
AwsProfileFileLocationProvider.DEFAULT_CONFIG_LOCATION_PROVIDER.getLocation()).getProfiles().values().stream(),
BasicProfileConfigLoader.INSTANCE.loadProfiles(
AwsProfileFileLocationProvider.DEFAULT_CREDENTIALS_LOCATION_PROVIDER.getLocation()).getProfiles().values().stream())
.map(profile -> new BasicProfile(profile.getProfileName().replaceFirst("^profile ", ""), profile.getProperties()))
.collect(Collectors.toMap(profile -> profile.getProfileName(), profile -> profile,
(left, right) -> {
final Map<String, String> properties = new HashMap<>(left.getProperties());
properties.putAll(right.getProperties());
return new BasicProfile(left.getProfileName(), properties);
})));

return allProfiles;
}

protected boolean validateCredentialProfilesExist() {
return AwsProfileFileLocationProvider.DEFAULT_CREDENTIALS_LOCATION_PROVIDER.getLocation() != null;

@Nullable
private ProfileStaticCredentialsProvider tryCreateProfileCredentialsProvider(BasicProfile profile) {
try {
return new ProfileStaticCredentialsProvider(profile);
} catch (SdkClientException e) {
e.printStackTrace();
getLogger().logError("Cannot load the profile \"%s\": %s", profile.getProfileName(), e.getMessage());
return null;
}
}

private AWSCredentialsProvider tryDefaultAwsCredentialsProviderChain() {
getLogger().logDebug("Trying to use default AWS credentials provider chain:");
DefaultAWSCredentialsProviderChain defaultAWSCredentialsProviderChain = DefaultAWSCredentialsProviderChain.getInstance();
AWSCredentials credentials = defaultAWSCredentialsProviderChain.getCredentials();
if (!isEmpty(credentials.getAWSSecretKey()) && !isEmpty(credentials.getAWSAccessKeyId())) {
getLogger().logError("Found credentials for default AWS credentials provider chain.");
} else {
getLogger().logError("Invalid or not defined AWSSecretKey or AWSAccessKeyId for default AWS credentials provider chain.");
}
return defaultAWSCredentialsProviderChain;
}

public Regions getRegion() {
return region;
protected boolean validateCredentialProfilesExist() {
return AwsProfileFileLocationProvider.DEFAULT_CREDENTIALS_LOCATION_PROVIDER.getLocation() != null;
}

public String getCredentialProfileName() {
return credentialProfileName;
}

public String getRegionName() {
return this.regionName;
}

public abstract void shutdown();
}
Loading

0 comments on commit 23b4144

Please sign in to comment.