Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: googleapis/java-pubsublite-kafka
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.4
Choose a base ref
...
head repository: googleapis/java-pubsublite-kafka
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.1.0
Choose a head ref
  • 5 commits
  • 14 files changed
  • 4 contributors

Commits on Jan 4, 2023

  1. chore(main): release 1.0.5-SNAPSHOT (#374)

    🤖 I have created a release *beep* *boop*
    ---
    
    
    ### Updating meta-information for bleeding-edge SNAPSHOT release.
    
    ---
    This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please).
    release-please[bot] authored Jan 4, 2023
    Copy the full SHA
    c152761 View commit details

Commits on Jan 6, 2023

  1. feat: add pubsublite-kafka-auth module (#363)

    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * feat: Create AuthServer/ClientParameters
    
    * 🦉 Updates from OwlBot post-processor
    
    See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md
    
    Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
    dpcollins-google and gcf-owl-bot[bot] authored Jan 6, 2023
    Copy the full SHA
    6c99767 View commit details
  2. chore(deps): update dependency com.google.cloud:pubsublite-kafka to v…

    …1.0.4 (#375)
    
    * chore(deps): update dependency com.google.cloud:pubsublite-kafka to v1.0.4
    
    * 🦉 Updates from OwlBot post-processor
    
    See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md
    
    Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
    renovate-bot and gcf-owl-bot[bot] authored Jan 6, 2023
    Copy the full SHA
    75b9a73 View commit details
  3. fix: update pom to add comment (#378)

    Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
    - [ ] Make sure to open an issue as a [bug/issue](https://togithub.com/googleapis/java-pubsublite-kafka/issues/new/choose) before writing your code!  That way we can discuss the change, evaluate designs, and agree on the general idea
    - [ ] Ensure the tests and linter pass
    - [ ] Code coverage does not decrease (if any source code was changed)
    - [ ] Appropriate docs were updated (if necessary)
    
    Fixes #<issue_number_goes_here> ☕️
    
    If you write sample code, please follow the [samples format](
    https://togithub.com/GoogleCloudPlatform/java-docs-samples/blob/main/SAMPLE_FORMAT.md).
    dpcollins-google authored Jan 6, 2023
    Copy the full SHA
    f658ed3 View commit details
  4. chore(main): release 1.1.0 (#377)

    Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
    release-please[bot] authored Jan 6, 2023
    Copy the full SHA
    7c7e03c View commit details
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## [1.1.0](https://github.com/googleapis/java-pubsublite-kafka/compare/v1.0.4...v1.1.0) (2023-01-06)


### Features

* Add pubsublite-kafka-auth module ([#363](https://github.com/googleapis/java-pubsublite-kafka/issues/363)) ([6c99767](https://github.com/googleapis/java-pubsublite-kafka/commit/6c99767e4ba841ec0d45e20a7f07003e2f7e3a42))


### Bug Fixes

* Update pom to add comment ([#378](https://github.com/googleapis/java-pubsublite-kafka/issues/378)) ([f658ed3](https://github.com/googleapis/java-pubsublite-kafka/commit/f658ed353da2bd60d31a451f751f116378e22c2c))

## [1.0.4](https://github.com/googleapis/java-pubsublite-kafka/compare/v1.0.3...v1.0.4) (2023-01-04)


7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -19,20 +19,20 @@ If you are using Maven, add this to your pom.xml file:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>pubsublite-kafka</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>
</dependency>
```

If you are using Gradle without BOM, add this to your dependencies:

```Groovy
implementation 'com.google.cloud:pubsublite-kafka:1.0.3'
implementation 'com.google.cloud:pubsublite-kafka:1.0.4'
```

If you are using SBT, add this to your dependencies:

```Scala
libraryDependencies += "com.google.cloud" % "pubsublite-kafka" % "1.0.3"
libraryDependencies += "com.google.cloud" % "pubsublite-kafka" % "1.0.4"
```

## Authentication
@@ -160,6 +160,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsublite-ka
| Sample | Source Code | Try it |
| --------------------------- | --------------------------------- | ------ |
| Consumer Example | [source code](https://github.com/googleapis/java-pubsublite-kafka/blob/main/samples/snippets/src/main/java/pubsublite/ConsumerExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsublite-kafka&page=editor&open_in_editor=samples/snippets/src/main/java/pubsublite/ConsumerExample.java) |
| Kafka Producer Example | [source code](https://github.com/googleapis/java-pubsublite-kafka/blob/main/samples/snippets/src/main/java/pubsublite/KafkaProducerExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsublite-kafka&page=editor&open_in_editor=samples/snippets/src/main/java/pubsublite/KafkaProducerExample.java) |
| Producer Example | [source code](https://github.com/googleapis/java-pubsublite-kafka/blob/main/samples/snippets/src/main/java/pubsublite/ProducerExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsublite-kafka&page=editor&open_in_editor=samples/snippets/src/main/java/pubsublite/ProducerExample.java) |


70 changes: 70 additions & 0 deletions kafka_gcp_credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import base64
import datetime
import google.auth
import google.auth.transport.urllib3
import http.server
import json
import urllib3

_credentials, _project = google.auth.default()
_http_client = urllib3.PoolManager()


def valid_credentials():
if not _credentials.valid:
_credentials.refresh(
google.auth.transport.urllib3.Request(_http_client))
return _credentials


_HEADER = json.dumps(dict(typ='JWT', alg='GOOG_TOKEN'))


def get_jwt(creds):
return json.dumps(dict(exp=creds.expiry.timestamp(),
iat=datetime.datetime.utcnow().timestamp(),
scope='pubsub',
sub='unused'))


def b64_encode(source):
return base64.urlsafe_b64encode(source.encode('utf-8')).decode('utf-8')


def get_kafka_access_token(creds):
return '.'.join([b64_encode(_HEADER), b64_encode(get_jwt(creds)),
b64_encode(creds.token)])


def build_message():
creds = valid_credentials()
expiry_seconds = (creds.expiry - datetime.datetime.utcnow()).total_seconds()
return json.dumps(
dict(access_token=get_kafka_access_token(creds), token_type='bearer',
expires_in=expiry_seconds))


class AuthHandler(http.server.BaseHTTPRequestHandler):
def _handle(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(build_message().encode('utf-8'))

def do_GET(self):
self._handle()

def do_POST(self):
self._handle()


def run_server():
server_address = ('localhost', 14293)
server = http.server.ThreadingHTTPServer(server_address, AuthHandler)
print("Serving on localhost:14293. This is not accessible outside of the "
"current machine.")
server.serve_forever()


if __name__ == '__main__':
run_server()
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -8,13 +8,14 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.cloud</groupId>
<artifactId>pubsublite-kafka-parent</artifactId>
<version>1.0.4</version><!-- {x-version-update:pubsublite-kafka:current} -->
<version>1.1.0</version><!-- {x-version-update:pubsublite-kafka:current} -->
<packaging>pom</packaging>
<name>Pub/Sub Lite Kafka Parent</name>
<url>https://github.com/googleapis/java-pubsublite-kafka</url>
<description>Parent POM for Pub/Sub Lite Kafka Integrations</description>
<modules>
<module>pubsublite-kafka</module>
<module>pubsublite-kafka-auth</module>
</modules>
<properties>
<psl.version>1.9.2</psl.version>
34 changes: 34 additions & 0 deletions pubsublite-kafka-auth/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.google.cloud</groupId>
<artifactId>pubsublite-kafka-parent</artifactId>
<version>1.1.0</version><!-- {x-version-update:pubsublite-kafka:current} -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.cloud</groupId>
<artifactId>pubsublite-kafka-auth</artifactId>
<version>1.1.0</version><!-- {x-version-update:pubsublite-kafka:current} -->
<packaging>jar</packaging>
<name>Pub/Sub Lite Kafka Auth</name>
<url>https://github.com/googleapis/java-pubsublite-kafka</url>
<description>Kafka Auth Provider for Google Cloud Pub/Sub Lite</description>
<dependencies>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsublite</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.pubsublite.kafka;

import com.google.cloud.pubsublite.CloudRegion;
import com.google.cloud.pubsublite.ProjectId;
import com.google.cloud.pubsublite.ProjectIdOrNumber;
import com.google.cloud.pubsublite.ProjectNumber;
import com.google.cloud.pubsublite.kafka.internal.AuthServer;
import java.util.HashMap;
import java.util.Map;

/** A class providing the correct parameters for connecting a Kafka client to Pub/Sub Lite. */
public final class ClientParameters {
public static Map<String, Object> getProducerParams(ProjectId project, CloudRegion region) {
return getProducerParams(ProjectIdOrNumber.of(project), region);
}

public static Map<String, Object> getProducerParams(ProjectNumber project, CloudRegion region) {
return getProducerParams(ProjectIdOrNumber.of(project), region);
}

public static Map<String, Object> getProducerParams(
ProjectIdOrNumber project, CloudRegion region) {
HashMap<String, Object> params = new HashMap<>();
params.put("enable.idempotence", false);
params.put("bootstrap.servers", getEndpoint(region));
params.put("security.protocol", "SASL_SSL");
params.put("sasl.mechanism", "OAUTHBEARER");
params.put("sasl.oauthbearer.token.endpoint.url", "http://localhost:" + AuthServer.PORT);
params.put("sasl.jaas.config", getJaasConfig(project));
params.put(
"sasl.login.callback.handler.class",
"org.apache.kafka.common.security.oauthbearer.secured.OAuthBearerLoginCallbackHandler");
return params;
}

private static String getEndpoint(CloudRegion region) {
return region.value() + "-kafka-pubsub.googleapis.com:443";
}

private static String getJaasConfig(ProjectIdOrNumber project) {
return String.format(
"org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId=\"unused\" clientSecret=\"unused\" extension_pubsubProject=\"%s\";",
project);
}

private ClientParameters() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.pubsublite.kafka.internal;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singletonList;

import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.time.Instant;
import java.util.Base64;

public class AuthServer {
public static int PORT = 14293;
public static InetSocketAddress ADDRESS =
new InetSocketAddress(InetAddress.getLoopbackAddress(), PORT);

private static final String HEADER =
new Gson().toJson(ImmutableMap.of("typ", "JWT", "alg", "GOOG_TOKEN"));

static {
spawnDaemon();
}

private static String b64Encode(String data) {
return Base64.getUrlEncoder().encodeToString(data.getBytes(UTF_8));
}

private static String getJwt(AccessToken token) {
return new Gson()
.toJson(
ImmutableMap.of(
"exp",
token.getExpirationTime().toInstant().getEpochSecond(),
"iat",
Instant.now().getEpochSecond(),
"scope",
"pubsub",
"sub",
"unused"));
}

private static String getKafkaAccessToken(AccessToken token) {
return String.join(
".", b64Encode(HEADER), b64Encode(getJwt(token)), b64Encode(token.getTokenValue()));
}

private static String getResponse(GoogleCredentials creds) throws IOException {
creds.refreshIfExpired();
AccessToken token = creds.getAccessToken();
long exipiresInSeconds =
Duration.between(Instant.now(), token.getExpirationTime().toInstant()).getSeconds();
return new Gson()
.toJson(
ImmutableMap.of(
"access_token",
getKafkaAccessToken(token),
"token_type",
"bearer",
"expires_in",
Long.toString(exipiresInSeconds)));
}

private static void spawnDaemon() {
// Run spawn() in a daemon thread so the created threads are themselves daemons.
Thread thread = new Thread(AuthServer::spawn);
thread.setDaemon(true);
thread.start();
}

private static void spawn() {
try {
GoogleCredentials creds =
GoogleCredentials.getApplicationDefault()
.createScoped("https://www.googleapis.com/auth/cloud-platform");
HttpServer server = HttpServer.create(ADDRESS, 0);
server.createContext(
"/",
handler -> {
try {
byte[] response = getResponse(creds).getBytes(UTF_8);
handler.getResponseHeaders().put("Content-type", singletonList("text/plain"));
handler.sendResponseHeaders(200, response.length);
handler.getResponseBody().write(response);
handler.close();
} catch (Exception e) {
e.printStackTrace(System.err);
throw new RuntimeException(e);
}
});
server.start();
} catch (Exception e) {
e.printStackTrace(System.err);
throw new RuntimeException(e);
}
}
}
4 changes: 2 additions & 2 deletions pubsublite-kafka/pom.xml
Original file line number Diff line number Diff line change
@@ -3,12 +3,12 @@
<parent>
<groupId>com.google.cloud</groupId>
<artifactId>pubsublite-kafka-parent</artifactId>
<version>1.0.4</version><!-- {x-version-update:pubsublite-kafka:current} -->
<version>1.1.0</version><!-- {x-version-update:pubsublite-kafka:current} -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.cloud</groupId>
<artifactId>pubsublite-kafka</artifactId>
<version>1.0.4</version><!-- {x-version-update:pubsublite-kafka:current} -->
<version>1.1.0</version><!-- {x-version-update:pubsublite-kafka:current} -->
<packaging>jar</packaging>
<name>Pub/Sub Lite Kafka Shim</name>
<url>https://github.com/googleapis/java-pubsublite-kafka</url>
2 changes: 1 addition & 1 deletion samples/install-without-bom/pom.xml
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>pubsublite-kafka</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>
</dependency>
<!-- [END pubsublite-kafka_install_without_bom] -->
<dependency>
Loading