Skip to content

Conversation

KazuCocoa
Copy link
Member

@KazuCocoa KazuCocoa commented Aug 25, 2022

Change list

I'd like to add https://appiumpro.com/editions/86-connecting-directly-to-appium-hosts-in-distributed-environments for Java client. Other clients such as webdriverio, Ruby and Python already have them for long. If the response had directConnect capabilities, the appium client attempt to send requests to the directConnect one instead of the original URL.

  • directConnectProtocol
  • directConnectHost
  • directConnectPort
  • directConnectPath

or appium: prefixed ones.

Types of changes

What types of changes are you proposing/introducing to Java client?
Put an x in the boxes that apply

  • No changes in production code.
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Details

The main change is setDirectConnect in src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java
To allow users to turn it on/off, I've added AppiumClientConfig and give the instance to the driver.

The example code is like...

     * AppiumClientConfig clientConfig = AppiumClientConfig.defaultConfig()
     *     .baseUri(URI.create("WebDriver URL"))
     *     .readTimeout(Duration.ofMinutes(5));
     * WindowsOptions options = new WindowsOptions();
     * WindowsDriver driver = new WindowsDriver(clientConfig, options);

By inheriting ClientConfig, we can set a custom User Agent as well. This PR includes the way to set the UA like appium/8.3.0 (selenium/4.5.0 (java mac))

The naming and implementation methods in AppiumClientConfig follow ClientConfig as possible.
ImeHandler removal in the test code was selenium 4.5.0 removed it.

@KazuCocoa KazuCocoa changed the title Direct connect feat: add directConnect feature Aug 25, 2022
@KazuCocoa KazuCocoa marked this pull request as ready for review August 25, 2022 05:58
@mykola-mokhnach
Copy link
Contributor

mykola-mokhnach commented Aug 25, 2022

I assume a vanilla redirect (code 302) would work better for such purpose than all this logic with response parsing and multiple values that eventually construct the same resulting url

@KazuCocoa
Copy link
Member Author

I agree with your intention basically, but I think the behavior was a bit different by this.:
Redirect changes the url after calling the default webdriver URL by getting 302, so basically, every request goes through the default webdrier URL (and redirects to another URL).
https://appiumpro.com/editions/86-connecting-directly-to-appium-hosts-in-distributed-environments idea was a new session request went thought the webdriver URL and created a session against behind a middle server (managed distributed hosts/devices like selenium grid), and then following request in the session would reach directConnect one directly instead of the original webdrievr URL to reduce HTTP request's latency.

@mykola-mokhnach
Copy link
Contributor

I agree with your intention basically, but I think the behavior was a bit different by this.:
Redirect changes the url after calling the default webdriver URL by getting 302, so basically, every request goes through the default webdrier URL (and redirects to another URL).
https://appiumpro.com/editions/86-connecting-directly-to-appium-hosts-in-distributed-environments idea was a new session request went thought the webdriver URL and created a session against behind a middle server (managed distributed hosts/devices like selenium grid), and then following request in the session would reach directConnect one directly instead of the original webdrievr URL to reduce HTTP request's latency.

Thanks for the explanation. In such case redirect is probably won't work, although I still don't see an actual need to provide 4 different values if we still need to combine them into a single url. It would probably too late to change the current implementation as it is already present in other clients

@KazuCocoa
Copy link
Member Author

thanks.
Yea, I came up with the same thought after a while... > a single url

@KazuCocoa KazuCocoa marked this pull request as draft August 25, 2022 16:39
@KazuCocoa
Copy link
Member Author

Changed to draft to update reviews

@KazuCocoa KazuCocoa mentioned this pull request Oct 20, 2022
4 tasks
@KazuCocoa
Copy link
Member Author

Updated. #1779 includes UA stuff as another PR

@KazuCocoa KazuCocoa marked this pull request as ready for review October 20, 2022 07:41

private final AppiumClientConfig appiumClientConfig;

private static class DirectConnect {
Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Oct 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say it is ok to have this class public. Also, you could use lombok for this purpose, which greatly reduces the amount of boilerplate code for POJOs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also having it public simplifies unit testing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to a new public class file. I'll try the lambok later as another pr after the UA change (So far, I've left a TODO comment)

private static final String DIRECT_CONNECT_HOST = "directConnectHost";
private static final String DIRECT_CONNECT_PORT = "directConnectPort";

public final String protocol;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please create public accessors rather than making properties public (e.g. protocol -> getProtocol()). Later we could simplify that code with lombok

class DirectConnectTest {

@Test
void hasValidDirectConnectValuesWithoutAppiumPrefix() throws MalformedURLException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

@Test
void hasValidDirectConnectInvalid() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test name does not make much sense to me

@KazuCocoa KazuCocoa merged commit 898d7ee into appium:master Oct 23, 2022

@Override
public AppiumClientConfig readTimeout(Duration timeout) {
ClientConfig clientConfig = super.connectionTimeout(timeout);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should call super.readTimeout(timeout)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, fixed in #1959

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants