Skip to content

Proxy support for browserstack plugin #28

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

Merged
merged 18 commits into from
Nov 11, 2020
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
24 changes: 15 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>

<artifactId>browserstack-integration</artifactId>
<version>1.1.9-SNAPSHOT</version>
<version>1.1.10-SNAPSHOT</version>
<packaging>hpi</packaging>

<name>BrowserStack</name>
Expand Down Expand Up @@ -102,6 +102,18 @@

<dependencies>

<dependency>
<groupId>com.brsanthu</groupId>
<artifactId>google-analytics-java</artifactId>
<version>1.1.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
Expand Down Expand Up @@ -138,7 +150,7 @@
<dependency>
<groupId>com.browserstack</groupId>
<artifactId>automate-client-java</artifactId>
<version>0.5</version>
<version>0.6</version>
</dependency>

<dependency>
Expand All @@ -150,7 +162,7 @@
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
<version>1.11</version>
</dependency>

<dependency>
Expand All @@ -165,12 +177,6 @@
<version>1.10</version>
</dependency>

<dependency>
<groupId>com.brsanthu</groupId>
<artifactId>google-analytics-java</artifactId>
<version>1.1.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.browserstack.automate.ci.common.proxysettings;

import hudson.ProxyConfiguration;
import jenkins.model.Jenkins;

import java.net.InetSocketAddress;
import java.net.Proxy;

public class JenkinsProxySettings {

private static final ProxyConfiguration jenkinsProxy = Jenkins.getInstanceOrNull() != null ? Jenkins.getInstanceOrNull().proxy : null;
private static final String protocol = "https";
private static final String systemProxyHost = System.getProperty(protocol + ".proxyHost");
private static final int systemProxyPort = Integer.parseInt(System.getProperty(protocol + ".proxyPort", "0"));
private static final String systemProxyUser = System.getProperty(protocol + ".proxyUser");
private static final String systemProxyPassword = System.getProperty(protocol + ".proxyPassword");

public static Proxy getJenkinsProxy() {
if (hasSystemProxy()) {
return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(systemProxyHost, systemProxyPort));
}

if (jenkinsProxy == null) return null;
final String proxyHost = jenkinsProxy.name;
final int proxyPort = jenkinsProxy.port;
return (proxyHost != null && proxyPort != 0) ? new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)) : null;
}

public static String getHost() {
if (hasSystemProxy()) {
return systemProxyHost;
}

if (jenkinsProxy == null) return null;
return jenkinsProxy.name;
}

public static int getPort() {
if (hasSystemProxy()) {
return systemProxyPort;
}

if (jenkinsProxy == null) return 0;
return jenkinsProxy.port;
}

public static String getUsername() {
if (hasSystemProxy() && systemProxyUser != null && systemProxyPassword != null) {
return systemProxyUser;
}

if (jenkinsProxy == null) return null;
return jenkinsProxy.getUserName();
}

public static String getPassword() {
if (hasSystemProxy() && systemProxyUser != null && systemProxyPassword != null) {
return systemProxyPassword;
}

if (jenkinsProxy == null) return null;
return jenkinsProxy.getPassword();
}

public static ProxyConfiguration getProxyConfig() {
return jenkinsProxy;
}

public static boolean hasProxy() {
return getHost() != null && getPort() != 0;
}

public static boolean hasSystemProxy() {
return systemProxyHost != null && systemProxyPort != 0;
}

}
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
package com.browserstack.automate.ci.common.tracking;


import com.browserstack.automate.ci.common.Tools;
import com.browserstack.automate.ci.common.constants.Constants;
import com.browserstack.automate.ci.common.proxysettings.JenkinsProxySettings;
import okhttp3.Authenticator;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Credentials;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.Route;
import org.json.JSONObject;

import java.io.IOException;
import java.net.Proxy;
import java.time.Instant;
import java.util.Optional;

public class PluginsTracker {
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
private static final String URL = "https://api.browserstack.com/ci_plugins/track";
private static final OkHttpClient client = new OkHttpClient();
private static OkHttpClient client;
private final String trackingId;
private String username;
private String accessKey;
Expand All @@ -27,12 +33,14 @@ public PluginsTracker(final String username, final String accessKey) {
this.username = username;
this.accessKey = accessKey;
this.trackingId = Tools.getUniqueString(true, true);
initializeClient();
}

public PluginsTracker() {
this.username = null;
this.accessKey = null;
this.trackingId = Tools.getUniqueString(true, true);
initializeClient();
}

private static void asyncPostRequestSilent(final String url, final String json) {
Expand All @@ -57,6 +65,31 @@ public void onResponse(Call call, Response response) throws IOException {
});
}

private void initializeClient() {

final Proxy proxy = JenkinsProxySettings.getJenkinsProxy() != null ? JenkinsProxySettings.getJenkinsProxy() : Proxy.NO_PROXY;
if (proxy != Proxy.NO_PROXY) {
final String username = JenkinsProxySettings.getUsername();
final String password = JenkinsProxySettings.getPassword();
if (username != null && password != null) {
Authenticator proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
final String credential = Credentials.basic(username, password);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
};
this.client = new OkHttpClient.Builder().proxy(proxy).proxyAuthenticator(proxyAuthenticator).build();
} else {
this.client = new OkHttpClient.Builder().proxy(proxy).build();
}
} else {
this.client = new OkHttpClient.Builder().build();
}
}

public void trackOperation(String operationType, JSONObject data) {
JSONObject requestData = new JSONObject();
requestData.put("source", Constants.JENKINS_CI_PLUGIN);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
package com.browserstack.automate.ci.common.uploader;

import java.io.FileNotFoundException;

import com.browserstack.appautomate.AppAutomateClient;
import com.browserstack.automate.ci.common.proxysettings.JenkinsProxySettings;
import com.browserstack.automate.ci.jenkins.BrowserStackCredentials;
import com.browserstack.automate.exception.AppAutomateException;
import com.browserstack.automate.exception.InvalidFileExtensionException;

public class AppUploader {

String appPath;
BrowserStackCredentials credentials;
String appPath;
BrowserStackCredentials credentials;

public AppUploader(String appPath, BrowserStackCredentials credentials) {
this.appPath = appPath;
this.credentials = credentials;
}
public AppUploader(String appPath, BrowserStackCredentials credentials) {
this.appPath = appPath;
this.credentials = credentials;
}

public String uploadFile()
throws AppAutomateException, FileNotFoundException, InvalidFileExtensionException {
AppAutomateClient appAutomateClient =
new AppAutomateClient(credentials.getUsername(), credentials.getDecryptedAccesskey());
return appAutomateClient.uploadApp(this.appPath).getAppUrl();
}
public String uploadFile()
throws AppAutomateException, FileNotFoundException, InvalidFileExtensionException {
AppAutomateClient appAutomateClient =
new AppAutomateClient(credentials.getUsername(), credentials.getDecryptedAccesskey());
if (JenkinsProxySettings.hasProxy()) {
appAutomateClient.setProxy(JenkinsProxySettings.getHost(), JenkinsProxySettings.getPort(), JenkinsProxySettings.getUsername(), JenkinsProxySettings.getPassword());
}
return appAutomateClient.uploadApp(this.appPath).getAppUrl();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.browserstack.automate.ci.common.analytics.Analytics;
import com.browserstack.automate.ci.common.enums.ProjectType;
import com.browserstack.automate.ci.common.model.BrowserStackSession;
import com.browserstack.automate.ci.common.proxysettings.JenkinsProxySettings;
import com.browserstack.automate.ci.jenkins.BrowserStackBuildWrapper.BuildWrapperItem;
import com.browserstack.automate.exception.AppAutomateException;
import com.browserstack.automate.exception.AutomateException;
Expand Down Expand Up @@ -112,6 +113,9 @@ private Session getSession(BrowserStackCredentials credentials, ProjectType proj
} else {
client = new AutomateClient(credentials.getUsername(), credentials.getDecryptedAccesskey());
}
if (JenkinsProxySettings.hasProxy()) {
client.setProxy(JenkinsProxySettings.getHost(), JenkinsProxySettings.getPort(), JenkinsProxySettings.getUsername(), JenkinsProxySettings.getPassword());
}
try {
activeSession = client.getSession(this.browserStackSession.getSessionId());
Analytics.trackIframeRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.browserstack.automate.AutomateClient;
import com.browserstack.automate.ci.common.analytics.Analytics;
import com.browserstack.automate.ci.common.proxysettings.JenkinsProxySettings;
import com.browserstack.automate.exception.AutomateException;
import com.cloudbees.plugins.credentials.BaseCredentials;
import com.cloudbees.plugins.credentials.CredentialsDescriptor;
Expand Down Expand Up @@ -72,6 +73,9 @@ public static FormValidation testAuthentication(final String username, final Str

try {
AutomateClient client = new AutomateClient(username, accesskey);
if (JenkinsProxySettings.hasProxy()) {
client.setProxy(JenkinsProxySettings.getHost(), JenkinsProxySettings.getPort(), JenkinsProxySettings.getUsername(), JenkinsProxySettings.getPassword());
}
if (client.getAccountUsage() != null) {
return FormValidation.ok(OK_VALID_AUTH);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.browserstack.automate.ci.common.Tools;
import com.browserstack.automate.ci.common.constants.Constants;
import com.browserstack.automate.ci.common.enums.ProjectType;
import com.browserstack.automate.ci.common.proxysettings.JenkinsProxySettings;
import com.browserstack.automate.ci.common.tracking.PluginsTracker;
import com.browserstack.automate.exception.BuildNotFound;
import com.browserstack.automate.model.Build;
Expand Down Expand Up @@ -86,6 +87,9 @@ private void fetchBuildAndSessions() {
} else {
client = new AutomateClient(credentials.getUsername(), credentials.getDecryptedAccesskey());
}
if (JenkinsProxySettings.hasProxy()) {
client.setProxy(JenkinsProxySettings.getHost(), JenkinsProxySettings.getPort(), JenkinsProxySettings.getUsername(), JenkinsProxySettings.getPassword());
}

browserStackBuild = fetchBrowserStackBuild(client, buildName);

Expand Down