Skip to content

Commit a583719

Browse files
Support head operations (#232)
## Changes Support head operations ## Tests Generated SDK and run Files integration tests.
1 parent 8c41892 commit a583719

File tree

11 files changed

+125
-17
lines changed

11 files changed

+125
-17
lines changed

.codegen/impl.java.tmpl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ class {{.PascalName}}Impl implements {{.PascalName}}Service {
3333
{{ template "api-call" . }}
3434
{{- else if .Response.ArrayValue -}} return apiClient.getCollection(path, null, {{template "type" .Response.ArrayValue}}.class, headers);
3535
{{- else if .Response.MapValue -}} return apiClient.getStringMap(path, {{ template "request-param" .}}, headers);
36-
{{- else if .IsResponseByteStream -}}
37-
InputStream response = {{ template "api-call" . }}
38-
return new {{ .Response.PascalName }}().set{{.ResponseBodyField.PascalName}}(response);
3936
{{- else }}return {{ template "api-call" . }}
4037
{{- end}}
4138
}
@@ -46,7 +43,6 @@ class {{.PascalName}}Impl implements {{.PascalName}}Service {
4643
apiClient.{{.Verb}}(path
4744
{{- if .Request}}, {{ template "request-param" .}}{{end}}
4845
, {{ if not .Response -}}Void
49-
{{- else if .IsResponseByteStream}}InputStream
5046
{{- else}}{{template "type" .Response}}{{- end -}}.class
5147
, headers);
5248
{{- end }}

.codegen/model.java.tmpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import java.util.Collection;
1010
import java.util.Objects;
1111

1212
import com.databricks.sdk.support.Generated;
13+
import com.databricks.sdk.support.Header;
1314
import com.databricks.sdk.support.QueryParam;
1415
import com.databricks.sdk.support.ToStringer;
1516

@@ -29,7 +30,7 @@ public class {{.PascalName}} {
2930
/**
3031
{{.Comment " * " 80}}
3132
*/
32-
{{if .IsJson}}@JsonProperty("{{.Name}}"){{end}}{{if .IsQuery}}@QueryParam("{{.Name}}"){{end}}
33+
{{if .IsJson}}@JsonProperty("{{.Name}}"){{end}}{{if .IsQuery}}@QueryParam("{{.Name}}"){{end}}{{if .IsHeader}}@Header("{{.Name}}"){{end}}
3334
private {{template "type" .Entity }} {{.CamelName}}{{if .IsNameReserved}}Value{{end}};
3435
{{end}}
3536

databricks-sdk-java/src/main/java/com/databricks/sdk/core/ApiClient.java

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.databricks.sdk.core.http.Response;
77
import com.databricks.sdk.core.utils.SystemTimer;
88
import com.databricks.sdk.core.utils.Timer;
9+
import com.databricks.sdk.support.Header;
910
import com.fasterxml.jackson.annotation.JsonInclude;
1011
import com.fasterxml.jackson.core.JsonProcessingException;
1112
import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -14,6 +15,7 @@
1415
import com.fasterxml.jackson.databind.SerializationFeature;
1516
import java.io.IOException;
1617
import java.io.InputStream;
18+
import java.lang.reflect.Field;
1719
import java.util.*;
1820
import org.slf4j.Logger;
1921
import org.slf4j.LoggerFactory;
@@ -131,6 +133,18 @@ protected <I, O> O withJavaType(
131133
}
132134
}
133135

136+
public <O> O HEAD(String path, Class<O> target, Map<String, String> headers) {
137+
return HEAD(path, null, target, headers);
138+
}
139+
140+
public <I, O> O HEAD(String path, I in, Class<O> target, Map<String, String> headers) {
141+
try {
142+
return execute(prepareRequest("HEAD", path, in, headers), target);
143+
} catch (IOException e) {
144+
throw new DatabricksException("IO error: " + e.getMessage(), e);
145+
}
146+
}
147+
134148
public <O> O GET(String path, Class<O> target, Map<String, String> headers) {
135149
return GET(path, null, target, headers);
136150
}
@@ -212,7 +226,7 @@ private <T> T execute(Request in, Class<T> target) throws IOException {
212226
if (target == Void.class) {
213227
return null;
214228
}
215-
return deserialize(out.getBody(), target);
229+
return deserialize(out, target);
216230
}
217231

218232
private Response getResponse(Request in) {
@@ -319,11 +333,18 @@ private String makeLogRecord(Request in, Response out) {
319333
return sb.toString();
320334
}
321335

322-
public <T> T deserialize(InputStream body, Class<T> target) throws IOException {
336+
public <T> T deserialize(Response response, Class<T> target) throws IOException {
323337
if (target == InputStream.class) {
324-
return (T) body;
338+
return (T) response.getBody();
325339
}
326-
return mapper.readValue(body, target);
340+
T object;
341+
try {
342+
object = target.getDeclaredConstructor().newInstance();
343+
} catch (Exception e) {
344+
throw new DatabricksException("Unable to initialize an instance of type " + target.getName());
345+
}
346+
deserialize(response, object);
347+
return object;
327348
}
328349

329350
public <T> T deserialize(InputStream body, JavaType target) throws IOException {
@@ -333,6 +354,60 @@ public <T> T deserialize(InputStream body, JavaType target) throws IOException {
333354
return mapper.readValue(body, target);
334355
}
335356

357+
private <T> void fillInHeaders(T target, Response response) {
358+
for (Field field : target.getClass().getDeclaredFields()) {
359+
Header headerAnnotation = field.getAnnotation(Header.class);
360+
if (headerAnnotation == null) {
361+
continue;
362+
}
363+
String firstHeader = response.getFirstHeader(headerAnnotation.value());
364+
if (firstHeader == null) {
365+
continue;
366+
}
367+
try {
368+
field.setAccessible(true);
369+
if (field.getType() == String.class) {
370+
field.set(target, firstHeader);
371+
} else if (field.getType() == Long.class) {
372+
field.set(target, Long.parseLong(firstHeader));
373+
} else {
374+
LOG.warn("Unsupported header type: " + field.getType());
375+
}
376+
} catch (IllegalAccessException e) {
377+
throw new DatabricksException("Failed to unmarshal headers: " + e.getMessage(), e);
378+
} finally {
379+
field.setAccessible(false);
380+
}
381+
}
382+
}
383+
384+
private <T> Optional<Field> getContentsField(T target) {
385+
for (Field field : target.getClass().getDeclaredFields()) {
386+
if (field.getName().equals("contents") && field.getType() == InputStream.class) {
387+
return Optional.of(field);
388+
}
389+
}
390+
return Optional.empty();
391+
}
392+
393+
public <T> void deserialize(Response response, T object) throws IOException {
394+
fillInHeaders(object, response);
395+
Optional<Field> contentsField = getContentsField(object);
396+
if (contentsField.isPresent()) {
397+
Field field = contentsField.get();
398+
try {
399+
field.setAccessible(true);
400+
field.set(object, response.getBody());
401+
} catch (IllegalAccessException e) {
402+
throw new DatabricksException("Failed to unmarshal headers: " + e.getMessage(), e);
403+
} finally {
404+
field.setAccessible(false);
405+
}
406+
} else if (response.getBody() != null) {
407+
mapper.readerForUpdating(object).readValue(response.getBody());
408+
}
409+
}
410+
336411
private String serialize(Object body) throws JsonProcessingException {
337412
if (body == null) {
338413
return null;

databricks-sdk-java/src/main/java/com/databricks/sdk/core/commons/CommonsHttpClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ private HttpUriRequest transformRequest(Request in) {
122122
switch (in.getMethod()) {
123123
case Request.GET:
124124
return new HttpGet(in.getUri());
125+
case Request.HEAD:
126+
return new HttpHead(in.getUri());
125127
case Request.DELETE:
126128
return new HttpDelete(in.getUri());
127129
case Request.POST:

databricks-sdk-java/src/main/java/com/databricks/sdk/core/http/Request.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
public class Request {
1212
public static final String GET = "GET";
13+
public static final String HEAD = "HEAD";
1314
public static final String DELETE = "DELETE";
1415
public static final String POST = "POST";
1516
public static final String PUT = "PUT";

databricks-sdk-java/src/main/java/com/databricks/sdk/service/billing/BillableUsageImpl.java

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

databricks-sdk-java/src/main/java/com/databricks/sdk/service/files/FilesImpl.java

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

databricks-sdk-java/src/main/java/com/databricks/sdk/service/serving/QueryEndpointResponse.java

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

databricks-sdk-java/src/main/java/com/databricks/sdk/service/sql/ChannelName.java

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.databricks.sdk.support;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/** Annotation to indicate that a field is a Header. */
9+
@Target({ElementType.FIELD})
10+
@Retention(RetentionPolicy.RUNTIME)
11+
public @interface Header {
12+
String value();
13+
}

0 commit comments

Comments
 (0)