Skip to content

Commit c0ef3f3

Browse files
committed
fix: Fix NPE
1 parent 2048a9b commit c0ef3f3

File tree

9 files changed

+147
-94
lines changed

9 files changed

+147
-94
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*-
2+
* -\-\-
3+
* github-api
4+
* --
5+
* Copyright (C) 2021 Spotify AB
6+
* --
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* -/-/-
19+
*/
20+
21+
package com.spotify.github.http;
22+
23+
import java.util.List;
24+
import java.util.Map;
25+
26+
public abstract class BaseHttpResponse implements HttpResponse {
27+
private static final int HTTP_OK = 200;
28+
private static final int HTTP_BAD_REQUEST = 400;
29+
30+
protected final HttpRequest request;
31+
protected final int statusCode;
32+
protected final String statusMessage;
33+
protected final Map<String, List<String>> headers;
34+
35+
public BaseHttpResponse(
36+
final HttpRequest request,
37+
final int statusCode,
38+
final String statusMessage,
39+
final Map<String, List<String>> headers) {
40+
this.request = request;
41+
this.statusCode = statusCode;
42+
this.statusMessage = statusMessage;
43+
this.headers = headers;
44+
}
45+
46+
@Override
47+
public HttpRequest request() {
48+
return request;
49+
}
50+
51+
public int statusCode() {
52+
return statusCode;
53+
}
54+
55+
@Override
56+
public String statusMessage() {
57+
return statusMessage;
58+
}
59+
60+
@Override
61+
public Map<String, List<String>> headers() {
62+
return this.headers;
63+
}
64+
65+
@Override
66+
public List<String> headers(final String headerName) {
67+
return this.headers.get(headerName);
68+
}
69+
70+
@Override
71+
public String header(final String headerName) {
72+
List<String> headerValues = this.headers(headerName);
73+
if (headerValues == null || headerValues.isEmpty()) {
74+
return null;
75+
}
76+
if (headerValues.size() == 1) {
77+
return headerValues.get(0);
78+
} else {
79+
return String.join(",", headerValues);
80+
}
81+
}
82+
83+
@Override
84+
public boolean isSuccessful() {
85+
return this.statusCode() >= HTTP_OK && this.statusCode() < HTTP_BAD_REQUEST;
86+
}
87+
}

src/main/java/com/spotify/github/http/HttpRequest.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2424
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
2525
import com.spotify.github.GithubStyle;
26-
import org.immutables.value.Value;
27-
2826
import java.util.List;
2927
import java.util.Map;
28+
import org.immutables.value.Value;
29+
30+
import javax.annotation.Nullable;
3031

3132
@Value.Immutable
3233
@GithubStyle
@@ -37,7 +38,27 @@ public interface HttpRequest {
3738

3839
String url();
3940

41+
@Nullable
4042
String body();
4143

42-
Map<String, List<String>> headers();
44+
@Value.Default
45+
default Map<String, List<String>> headers(){
46+
return Map.of();
47+
}
48+
49+
default List<String> headers(String headerName) {
50+
return headers().get(headerName);
51+
}
52+
53+
default String header(String headerName) {
54+
List<String> headerValues = this.headers(headerName);
55+
if (headerValues == null || headerValues.isEmpty()) {
56+
return null;
57+
}
58+
if (headerValues.size() == 1) {
59+
return headerValues.get(0);
60+
} else {
61+
return String.join(",", headerValues);
62+
}
63+
}
4364
}

src/main/java/com/spotify/github/http/HttpResponse.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,24 @@
2525
import java.util.Map;
2626

2727
public interface HttpResponse {
28+
// Returns the request that was sent to the server
2829
HttpRequest request();
30+
// Returns the HTTP status code
2931
int statusCode();
32+
// Returns the HTTP status message
3033
String statusMessage();
34+
// Returns the response body as an InputStream
3135
InputStream body();
36+
// Returns the response body as a String
3237
String bodyString();
38+
// Returns the response headers as a Map
3339
Map<String, List<String>> headers();
40+
// Returns the response headers for a specific header name as a list of Strings
41+
List<String> headers(String headerName);
42+
// Returns the response headers for a specific header name as a single String
43+
String header(String headerName);
44+
// Returns true if the response was successful
3445
boolean isSuccessful();
46+
// Closes the response
3547
void close();
3648
}

src/main/java/com/spotify/github/http/okhttp/OkHttpHttpResponse.java

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,56 +20,30 @@
2020

2121
package com.spotify.github.http.okhttp;
2222

23+
import com.spotify.github.http.BaseHttpResponse;
2324
import com.spotify.github.http.HttpRequest;
24-
import com.spotify.github.http.HttpResponse;
2525
import java.io.IOException;
2626
import java.io.InputStream;
2727
import java.io.UncheckedIOException;
2828
import java.lang.invoke.MethodHandles;
29-
import java.util.List;
30-
import java.util.Map;
3129
import java.util.Optional;
32-
3330
import okhttp3.Response;
3431
import okhttp3.ResponseBody;
3532
import org.slf4j.Logger;
3633
import org.slf4j.LoggerFactory;
3734

38-
public class OkHttpHttpResponse implements HttpResponse {
35+
public class OkHttpHttpResponse extends BaseHttpResponse {
3936
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
40-
private static final int HTTP_OK = 200;
41-
private static final int HTTP_BAD_REQUEST = 400;
42-
43-
private final HttpRequest request;
37+
4438
private final Response response;
45-
private final int statusCode;
46-
private final String statusMessage;
4739
private InputStream body;
48-
private final Map<String, List<String>> headers;
4940
private String bodyString;
5041

5142
public OkHttpHttpResponse(final HttpRequest request, final Response response) {
52-
this.request = request;
53-
this.statusCode = response.code();
54-
this.statusMessage = response.message();
55-
this.headers = response.headers().toMultimap();
43+
super(request, response.code(), response.message(), response.headers().toMultimap());
5644
this.response = response;
5745
}
5846

59-
@Override
60-
public HttpRequest request() {
61-
return request;
62-
}
63-
64-
public int statusCode() {
65-
return statusCode;
66-
}
67-
68-
@Override
69-
public String statusMessage() {
70-
return statusMessage;
71-
}
72-
7347
@Override
7448
public InputStream body() {
7549
if (body == null) {
@@ -87,16 +61,6 @@ public String bodyString() {
8761
return bodyString;
8862
}
8963

90-
@Override
91-
public Map<String, List<String>> headers() {
92-
return this.headers;
93-
}
94-
95-
@Override
96-
public boolean isSuccessful() {
97-
return this.statusCode() >= HTTP_OK && this.statusCode() < HTTP_BAD_REQUEST;
98-
}
99-
10064
@Override
10165
public void close() {
10266
try {

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetryTracer.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,7 @@ public String get(
118118
if (carrier == null) {
119119
return null;
120120
}
121-
if (carrier.headers().containsKey(key)
122-
&& !carrier.headers().get(key).isEmpty()) {
123-
return carrier.headers().get(key).get(0);
124-
}
125-
return null;
121+
return carrier.header(key);
126122
}
127123
});
128124
context.makeCurrent();

src/main/java/com/spotify/github/v3/clients/GithubPage.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
* Licensed under the Apache License, Version 2.0 (the "License");
88
* you may not use this file except in compliance with the License.
99
* You may obtain a copy of the License at
10-
*
10+
*
1111
* http://www.apache.org/licenses/LICENSE-2.0
12-
*
12+
*
1313
* Unless required by applicable law or agreed to in writing, software
1414
* distributed under the License is distributed on an "AS IS" BASIS,
1515
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -36,7 +36,6 @@
3636
import java.util.NoSuchElementException;
3737
import java.util.Optional;
3838
import java.util.concurrent.CompletableFuture;
39-
import java.util.stream.Stream;
4039

4140
/**
4241
* Async page implementation for github resources
@@ -145,9 +144,7 @@ public Iterator<T> iterator() {
145144
.request(path)
146145
.thenApply(
147146
response ->
148-
github
149-
.json()
150-
.fromJsonUncheckedNotNull(response.bodyString(), typeReference))
147+
github.json().fromJsonUncheckedNotNull(response.bodyString(), typeReference))
151148
.join()
152149
.iterator();
153150
}
@@ -157,12 +154,12 @@ private CompletableFuture<Map<String, Link>> linkMapAsync() {
157154
.request(path)
158155
.thenApply(
159156
response -> {
160-
return Optional.ofNullable(response.headers().get("Link").get(0))
161-
.map(linkHeader -> stream(linkHeader.split(",")))
162-
.orElseGet(Stream::empty)
163-
.map(linkString -> Link.from(linkString.split(";")))
164-
.filter(link -> link.rel().isPresent())
165-
.collect(toMap(link -> link.rel().get(), identity()));
157+
return Optional.ofNullable(response.header("Link"))
158+
.stream()
159+
.flatMap(linkHeader -> stream(linkHeader.split(",")))
160+
.map(linkString -> Link.from(linkString.split(";")))
161+
.filter(link -> link.rel().isPresent())
162+
.collect(toMap(link -> link.rel().get(), identity()));
166163
});
167164
}
168165

src/main/java/com/spotify/github/v3/issues/Issue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public interface Issue extends CloseTracking {
6767

6868
/** Number. */
6969
@Nullable
70-
Integer number();
70+
Long number();
7171

7272
/** Indicates the state of the issues to return. Can be either open, closed, or all. */
7373
@Nullable

src/test/java/com/spotify/github/v3/clients/MockHelper.java

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020

2121
package com.spotify.github.v3.clients;
2222

23+
import com.spotify.github.http.BaseHttpResponse;
2324
import com.spotify.github.http.HttpRequest;
2425
import com.spotify.github.http.HttpResponse;
2526
import com.spotify.github.http.ImmutableHttpRequest;
26-
2727
import java.io.ByteArrayInputStream;
2828
import java.io.IOException;
2929
import java.io.InputStream;
@@ -48,22 +48,12 @@ public static HttpResponse createMockHttpResponse(
4848
final int statusCode,
4949
final String body,
5050
final Map<String, List<String>> headers) {
51-
return new HttpResponse() {
52-
@Override
53-
public HttpRequest request() {
54-
return ImmutableHttpRequest.builder().url(url).build();
55-
}
56-
57-
@Override
58-
public int statusCode() {
59-
return statusCode;
60-
}
61-
62-
@Override
63-
public String statusMessage() {
64-
return "";
65-
}
66-
51+
HttpRequest httpRequest = ImmutableHttpRequest.builder()
52+
.method("GET")
53+
.body(null)
54+
.headers(Map.of())
55+
.url(url).build();
56+
return new BaseHttpResponse(httpRequest, statusCode, "", headers) {
6757
@Override
6858
public InputStream body() {
6959
if (body != null) {
@@ -77,22 +67,8 @@ public String bodyString() {
7767
return Optional.ofNullable(body).orElse("");
7868
}
7969

80-
@Override
81-
public Map<String, List<String>> headers() {
82-
return Optional.ofNullable(headers).orElse(Map.of());
83-
}
84-
85-
@Override
86-
public boolean isSuccessful() {
87-
return MockHelper.isSuccessful(statusCode);
88-
}
89-
9070
@Override
9171
public void close() {}
9272
};
9373
}
94-
95-
private static boolean isSuccessful(final int statusCode) {
96-
return statusCode >= HTTP_OK && statusCode < HTTP_BAD_REQUEST;
97-
}
9874
}

src/test/java/com/spotify/github/v3/search/SearchTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static final void assertSearchIssues(final SearchIssues search) {
4141
assertThat(
4242
issues.url(),
4343
is(URI.create("https://api.github.com/repos/batterseapower/pinyin-toolkit/issues/132")));
44-
assertThat(issues.number(), is(132));
44+
assertThat(issues.number(), is(132L));
4545
assertThat(issues.id(), is(35802L));
4646
assertThat(issues.title(), is("Line Number Indexes Beyond 20 Not Displayed"));
4747
}
@@ -65,6 +65,6 @@ public void testDeserializationWithLargeIssueId() throws IOException {
6565

6666
final Issue issue = search.items().get(0);
6767
assertThat(issue.id(), is(2592843837L));
68-
assertThat(issue.number(), is(5514));
68+
assertThat(issue.number(), is(5514L));
6969
}
7070
}

0 commit comments

Comments
 (0)