Using HTTP 2.0 in a binding

I am working on a binding to integrate a system where the supplier recommends using HTTP 2. I think that the OH core developers a pushing binding developers to use the ‘OH common HTTP client’. But I think that this common client currently only supports HTTP 1.x (??) => Does anyone have thoughts how I should proceed?

There is a HTTP2Client in jetty: org.eclipse.jetty.http2.client (Jetty :: Project 9.4.46.v20220331 API). Might that work for you? If we need an additional bundle for that, I would suggest to add it to the jetty feature in core, but for testing it should work to just add it to you binding’s pom.xml.

Thanks @J-N-K for the info. If I understand you correctly, you are saying four things: 1) that I should use Jetty instead of another client, 2) I should first import it locally into the binding, and 3) after the binding is proven, I should raise an Issue to add the Http2Client to the core, and finally 4) modify the binding to use the core client. Or??

Yes, but we don‘t need to wait for merging the new binding. Once it is clear that it‘s almost merged, we can add the code dependency, so you don‘t need a separate PR in addons to modify the POM. Just ping me if you are almost there.

1 Like

@J-N-K there seem to be a lot of cross dependencies between jetty modules, so can you please let me know what jetty versions are OH 3.4.Mx using, so I can add the jetty http2 modules from the same version set?

We are currently using <jetty.version>9.4.46.v20220331</jetty.version>, you can try if you can use <version>${jetty.version}</version> instead of using a version directly.

1 Like

@J-N-K 4yi I got it working with the hardcoded version Id in the pom, which builds Ok within the eclipse IDE. But I couldn’t persuade eclipse IDE to accept the parametrised version Id.

Nor could I persuade Maven to build it with either hardcoded Id or parametrised Id.

Also I found that in the pom, I seem to need to list both a) the dependencies on the modules actually used in the code, but also b) the dependencies that those modules have on other sub modules, which are not referenced directly by my code. => How should one correctly handle such sub dependencies? Does the OH build system auto magically pull in such sub dependencies, or must they be explicitly mentioned in the Pom?

Sorry, I forgot about this thread after reading it. Can you point me to the actual code?

Following is the jetty part of the imports for my class

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http.MetaData.Response;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise.Completable;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory.Client;

And below is the POM that I need in order to avoid “missing dependency” errors. The class imports three modules (org.eclipse.jetty.http2.api, org.eclipse.jetty.http2.client and org.eclipse.jetty.http2.frames) whereas the POM needs to declare four dependencies (http2-client, http2-common, http2-hpack, jetty-alpn-java-client). Also <version>${jetty.version}</version> in the POM does not work, and it needs <version>9.4.46.v20220331</version> instead.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.openhab.addons.bundles</groupId>
    <artifactId>org.openhab.addons.reactor.bundles</artifactId>
    <version>4.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>org.openhab.binding.hue</artifactId>
  <name>openHAB Add-ons :: Bundles :: hue Binding</name>
  <dependencies>
    <!-- TODO the following modules should be explicitly in OH core -->
    <dependency>
      <groupId>org.eclipse.jetty.http2</groupId>
      <artifactId>http2-client</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jetty.http2</groupId>
      <artifactId>http2-common</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jetty.http2</groupId>
      <artifactId>http2-hpack</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-alpn-java-client</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
  </dependencies>
</project>

Looks good to me. And all of these need to be added to the core-feature. I’m not sure if we should create a new feature for that or if we just extend the existing openhab.tp-httpclient because we already added web sockets there. We can discuss that if the general PR get’s accepted on openhab-addons. We can then add the core dependencies and features in a few days.

:slight_smile:

I can compile the binding JAR locally in Eclipse, and if I add the respective dependency JARS to the addons folder, it runs fine here.

BUT if I try to build the JAR via mvn clean install from the command line locally, the build part works OK, but verification part fails due to ‘missing requirement’ as shown below. And therefore I suppose the GitHub CI build process will also fail. And that would mean the OH maintainers might refuse the PR due to its failure of those tests.

=> @J-N-K any thoughts how to eliminate these Maven build (verify) errors?

Add the bundles to the feature.xml, that should do the trick, e.g.:

<bundle dependency="true">mvn:org.eclipse.jetty.http2/http2-client/9.4.46.v20220331</bundle>

Depending on the way it is added in core later this can bei either removed or needs some adjustment.

@J-N-K sorry for being a PITA but I still can’t get it to build in Maven…

Following is my feature.xml

<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.hue-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
	<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
	<feature name="openhab-binding-hue" description="Hue Binding" version="${project.version}">
		<feature>openhab-runtime-base</feature>
		<feature>openhab-transport-mdns</feature>
		<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.hue/${project.version}</bundle>
		<bundle dependency="true">mvn:org.eclipse.jetty.http2/http2-client/9.4.46.v20220331</bundle>
		<bundle dependency="true">mvn:org.eclipse.jetty.http2/http2-common/9.4.46.v20220331</bundle>
		<bundle dependency="true">mvn:org.eclipse.jetty.http2/http2-hpack/9.4.46.v20220331</bundle>
		<bundle dependency="true">mvn:org.eclipse.jetty/jetty-alpn-java-client/9.4.46.v20220331</bundle>
	</feature>
</features>

And following is my pom.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.openhab.addons.bundles</groupId>
    <artifactId>org.openhab.addons.reactor.bundles</artifactId>
    <version>4.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>org.openhab.binding.hue</artifactId>
  <name>openHAB Add-ons :: Bundles :: hue Binding</name>
  <dependencies>
    <!-- TODO the following modules should be explicitly in OH core -->
    <dependency>
      <groupId>org.eclipse.jetty.http2</groupId>
      <artifactId>http2-client</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jetty.http2</groupId>
      <artifactId>http2-common</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jetty.http2</groupId>
      <artifactId>http2-hpack</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-alpn-java-client</artifactId>
      <version>9.4.46.v20220331</version>
    </dependency>
  </dependencies>
</project>

Difficult. Is the message still exactly the same?

Yes it is the same.

The error relates to the org.eclipse.jetty/jetty-alpn-java-client/9.4.46.v20220331 dependency; this is a sub dependency that is not directly imported in my code; but if the dependency is not declared at compile time, then the binding produces a missing dependency error at runtime.

Is the code available on GitHub?

The code is in my PR for Hue CLIP 2 implementation 13570. Unfortunately the PR is currently in a messy state because it is ~80 commits behind main, and ~80 commits ahead of main, so there are some merge conflicts that I still need to resolve…

EDIT: the class to look for is called ‘Clip2Bridge’…

<bundle dependency="true">mvn:org.eclipse.jetty/jetty-alpn-client/9.4.46.v20220331</bundle>

missing in the feature.

1 Like

^
Thanks @J-N-K . I do have ‘jetty-alpn-java-client’ in both the pom and the feature. But you mentioned ‘jetty-alpn-client’ (without ‘java’ in the name). I am a bit confused, but it looks like the contents of one or the other of those modules was switched around between different Java versions. ??

@J-N-K I got it working when the binding sends HTTP/2.0 GET requests, but it fails when it sends a PUT request. Apparently the error is because the OH core OSGI service loader is not loading one of the Jetty HTTP transient dependency JARS as mentioned in this thread…