Skip to content
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ dependency-reduced-pom.xml
# mvn release
pom.xml.releaseBackup
release.properties

# macOS
.DS_Store
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
![lifecycle: beta](https://img.shields.io/badge/lifecycle-beta-509bf5.svg)
[![Maven Central](https://img.shields.io/maven-central/v/com.spotify/github-client)](https://mvnrepository.com/artifact/com.spotify/github-client)


# github-java-client

A small Java library for talking to GitHub/GitHub Enterprise and interacting with projects.
Expand Down Expand Up @@ -74,6 +73,7 @@ log.info(repositoryClient.getCommit("sha").get().htmlUrl());

Another example of the mirrored structure is that some of the APIs are nested under a parent API.
For example, endpoints related to check runs or issues are nested under the Repository client:

```java
final ChecksClient checksClient = repositoryClient.createChecksApiClient();
checksClient.createCheckRun(CHECK_RUN_REQUEST);
Expand All @@ -85,11 +85,51 @@ issueClient.createComment(ISSUE_ID, "comment body")
```

And endpoints related to teams and memberships are nested under the Organisation client:

```java
final TeamClient teamClient = organisationClient.createTeamClient();
teamClient.getMembership("username");
```

## Tracing

The GitHub client supports tracing via both OpenCensus and OpenTelemetry. Since OpenCensus is deprecated, we recommend
using OpenTelemetry. Using OpenTelemetry also enables context propagation when using this library.
To enable tracing, you need to provide a tracer when initializing the client.

### OpenTelemetry

```java
import com.spotify.github.tracing.opentelemetry.OpenTelemetryTracer;

final GitHubClient githubClient =
GitHubClient.create(baseUri, accessToken)
// Uses GlobalOpenTelemetry.get() to fetch the default tracer
.withTracer(new OpenTelemetryTracer());
```

You can also provide a custom `OpenTelemetry` object if you want to use a specific one.

```java
import com.spotify.github.tracing.opentelemetry.OpenTelemetryTracer;

final GitHubClient githubClient =
GitHubClient.create(baseUri, accessToken)
// Uses custom openTelemetry object to fetch the tracer
.withTracer(new OpenTelemetryTracer(openTelemetry));
```

### OpenCensus

```java
import com.spotify.github.tracing.opencensus.OpenCensusTracer;

final GitHubClient githubClient =
GitHubClient.create(baseUri, accessToken)
// Uses Tracing.getTracer() to fetch the default tracer
.withTracer(new OpenCensusTracer());
```

## Supported Java versions

This library is written and published with Java version 11. In our CI workflows, we execute
Expand All @@ -107,6 +147,7 @@ mvn clean verify
If you are a maintainer, you can release a new version by just triggering the workflow
[prepare-release](./.github/workflows/prepare-release.yml) through the
[web UI](https://github.com/spotify/github-java-client/actions/workflows/prepare-release.yml).

- Select whether the new release should be a `major`, `minor` or `patch` release
- Trigger the release preparation on the `master` branch
- Pushes of this workflow will trigger runs of the
Expand Down
51 changes: 33 additions & 18 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

<organization>
<name>Spotify AB</name>
<url>http://www.spotify.com</url>
<url>https://www.spotify.com</url>
</organization>

<distributionManagement>
Expand All @@ -42,23 +42,6 @@
</repository>
</distributionManagement>

<developers>
<developer>
<id>henriquetruta</id>
<name>Henrique Truta</name>
<email>[email protected]</email>
<organization>Spotify AB</organization>
<organizationUrl>http://www.spotify.com</organizationUrl>
</developer>
<developer>
<id>hewhomustnotbenamed</id>
<name>Abhimanyu Shegokar</name>
<email>[email protected]</email>
<organization>Spotify AB</organization>
<organizationUrl>http://www.spotify.com</organizationUrl>
</developer>
</developers>

<repositories>
<repository>
<id>apache.snapshots</id>
Expand Down Expand Up @@ -102,6 +85,7 @@
<objenesis.version>3.3</objenesis.version>
<opencensus.version>0.31.1</opencensus.version>
<okhttp.version>4.11.0</okhttp.version>
<opentelemetry.version>1.42.1</opentelemetry.version>

<shade.id>${project.groupId}.githubclient.shade</shade.id>
</properties>
Expand All @@ -120,6 +104,13 @@
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>${opentelemetry.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down Expand Up @@ -179,6 +170,30 @@
<artifactId>opencensus-api</artifactId>
<version>${opencensus.version}</version>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-testing</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-okhttp-3.0</artifactId>
<version>2.8.0-alpha</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
Expand Down
57 changes: 16 additions & 41 deletions src/main/java/com/spotify/github/opencensus/OpenCensusSpan.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
* 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.
Expand All @@ -19,45 +19,20 @@
*/

package com.spotify.github.opencensus;
import static java.util.Objects.requireNonNull;
import com.spotify.github.Span;
import com.spotify.github.v3.exceptions.RequestNotOkException;
import io.opencensus.trace.AttributeValue;
import io.opencensus.trace.Status;

class OpenCensusSpan implements Span {
import io.opencensus.trace.Span;

public static final int NOT_FOUND = 404;
public static final int INTERNAL_SERVER_ERROR = 500;
private final io.opencensus.trace.Span span;

OpenCensusSpan(final io.opencensus.trace.Span span) {
this.span = requireNonNull(span);
}

@Override
public Span success() {
span.setStatus(Status.OK);
return this;
}

@Override
public Span failure(final Throwable t) {
if (t instanceof RequestNotOkException) {
RequestNotOkException ex = (RequestNotOkException) t;
span.putAttribute("http.status_code", AttributeValue.longAttributeValue(ex.statusCode()));
span.putAttribute("message", AttributeValue.stringAttributeValue(ex.getRawMessage()));
if (ex.statusCode() - INTERNAL_SERVER_ERROR >= 0) {
span.putAttribute("error", AttributeValue.booleanAttributeValue(true));
}
}
span.setStatus(Status.UNKNOWN);
return this;
}

@Override
public void close() {
span.end();
}
/**
* OpenCensusSpan is a wrapper around OpenCensus Span. This class is kept for backward
* compatibility.
*
* @deprecated This class has been moved to the package com.spotify.github.tracing.opencensus.
* Please use com.spotify.github.tracing.opencensus.OpenCensusSpan instead.
*/
@Deprecated
public class OpenCensusSpan extends com.spotify.github.tracing.opencensus.OpenCensusSpan {
public OpenCensusSpan(final Span span) {
super(span);
}
// This class is kept for backward compatibility
}

64 changes: 13 additions & 51 deletions src/main/java/com/spotify/github/opencensus/OpenCensusTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
* -\-\-
* github-api
* --
* Copyright (C) 2021 Spotify AB
* Copyright (C) 2016 - 2021 Spotify AB
* --
* 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.
Expand All @@ -20,52 +20,14 @@

package com.spotify.github.opencensus;

import com.spotify.github.Span;
import com.spotify.github.Tracer;
import io.opencensus.trace.Tracing;

import java.util.concurrent.CompletionStage;

import static io.opencensus.trace.AttributeValue.stringAttributeValue;
import static io.opencensus.trace.Span.Kind.CLIENT;
import static java.util.Objects.requireNonNull;

public class OpenCensusTracer implements Tracer {

private static final io.opencensus.trace.Tracer TRACER = Tracing.getTracer();

@Override
public Span span(final String name, final String method, final CompletionStage<?> future) {
return internalSpan(name, method, future);
}

@SuppressWarnings("MustBeClosedChecker")
private Span internalSpan(
final String path,
final String method,
final CompletionStage<?> future) {
requireNonNull(path);
requireNonNull(future);

final io.opencensus.trace.Span ocSpan =
TRACER.spanBuilder("GitHub Request").setSpanKind(CLIENT).startSpan();

ocSpan.putAttribute("component", stringAttributeValue("github-api-client"));
ocSpan.putAttribute("peer.service", stringAttributeValue("github"));
ocSpan.putAttribute("http.url", stringAttributeValue(path));
ocSpan.putAttribute("method", stringAttributeValue(method));
final Span span = new OpenCensusSpan(ocSpan);

future.whenComplete(
(result, t) -> {
if (t == null) {
span.success();
} else {
span.failure(t);
}
span.close();
});

return span;
}
/**
* OpenCensusTracer is a wrapper around OpenCensus Tracer. This class is kept for backward
* compatibility.
*
* @deprecated This class has been moved to the package com.spotify.github.tracing.opencensus.
* Please use com.spotify.github.tracing.opencensus.OpenCensusTracer instead.
*/
@Deprecated
public class OpenCensusTracer extends com.spotify.github.tracing.opencensus.OpenCensusTracer {

Check warning on line 31 in src/main/java/com/spotify/github/opencensus/OpenCensusTracer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/opencensus/OpenCensusTracer.java#L31

Added line #L31 was not covered by tests
// This class is kept for backward compatibility
}
69 changes: 69 additions & 0 deletions src/main/java/com/spotify/github/tracing/BaseTracer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*-
* -\-\-
* github-client
* --
* Copyright (C) 2016 - 2021 Spotify AB
* --
* 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.spotify.github.tracing;

import okhttp3.Request;

import java.util.concurrent.CompletionStage;

public abstract class BaseTracer implements Tracer {
@Override
public Span span(final String name, final String method, final CompletionStage<?> future) {
return internalSpan(name, method, future);
}

@Override
public Span span(final String path, final String method) {
return internalSpan(path, method, null);

Check warning on line 35 in src/main/java/com/spotify/github/tracing/BaseTracer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/BaseTracer.java#L35

Added line #L35 was not covered by tests
}

@Override
public Span span(final Request request) {
return internalSpan(request, null);
}

@Override
public Span span(final Request request, final CompletionStage<?> future) {
return internalSpan(request, future);

Check warning on line 45 in src/main/java/com/spotify/github/tracing/BaseTracer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/BaseTracer.java#L45

Added line #L45 was not covered by tests
}

protected abstract Span internalSpan(
String path,
String method,
CompletionStage<?> future);

protected abstract Span internalSpan(
Request request,
CompletionStage<?> future);

@Override
public void attachSpanToFuture(final Span span, final CompletionStage<?> future) {
future.whenComplete(
(result, t) -> {
if (t == null) {
span.success();
} else {
span.failure(t);
}
span.close();
});
}
}
Loading