Skip to content

Commit d033416

Browse files
committed
wip
1 parent f4fdd50 commit d033416

File tree

10 files changed

+142
-43
lines changed

10 files changed

+142
-43
lines changed

java-client/src/main/java/co/elastic/clients/transport/DefaultTransportOptions.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class DefaultTransportOptions implements TransportOptions {
3838
private final Map<String, String> parameters;
3939
private final Function<List<String>, Boolean> onWarnings;
4040
private boolean keepResponseBodyOnException;
41+
private boolean enableServerlessMode;
4142

4243
public static final DefaultTransportOptions EMPTY = new DefaultTransportOptions();
4344

@@ -49,10 +50,12 @@ public DefaultTransportOptions(
4950
@Nullable HeaderMap headers,
5051
@Nullable Map<String, String> parameters,
5152
@Nullable Function<List<String>, Boolean> onWarnings,
52-
boolean keepResponseBodyOnException
53+
boolean keepResponseBodyOnException,
54+
boolean enableServerlessMode
5355
) {
5456
this(headers,parameters,onWarnings);
5557
this.keepResponseBodyOnException = keepResponseBodyOnException;
58+
this.enableServerlessMode = enableServerlessMode;
5659
}
5760

5861
public DefaultTransportOptions(
@@ -65,10 +68,11 @@ public DefaultTransportOptions(
6568
Collections.emptyMap() : Collections.unmodifiableMap(parameters);
6669
this.onWarnings = onWarnings;
6770
this.keepResponseBodyOnException = false;
71+
this.enableServerlessMode = false;
6872
}
6973

7074
protected DefaultTransportOptions(AbstractBuilder<?> builder) {
71-
this(builder.headers, builder.parameters, builder.onWarnings, builder.keepResponseBodyOnException);
75+
this(builder.headers, builder.parameters, builder.onWarnings, builder.keepResponseBodyOnException, builder.enableServerlessMode);
7276
}
7377

7478
public static DefaultTransportOptions of(@Nullable TransportOptions options) {
@@ -105,12 +109,16 @@ public void updateToken(String token) {
105109
this.headers.put("Authorization", "Bearer " + token);
106110
}
107111

108-
109112
@Override
110113
public boolean keepResponseBodyOnException() {
111114
return keepResponseBodyOnException;
112115
}
113116

117+
@Override
118+
public boolean enableServerlessMode() {
119+
return enableServerlessMode;
120+
}
121+
114122
@Override
115123
public Builder toBuilder() {
116124
return new Builder(this);
@@ -135,6 +143,7 @@ public abstract static class AbstractBuilder<BuilderT extends AbstractBuilder<Bu
135143
private Map<String, String> parameters;
136144
private Function<List<String>, Boolean> onWarnings;
137145
private boolean keepResponseBodyOnException;
146+
private boolean enableServerlessMode;
138147

139148
public AbstractBuilder() {
140149
}
@@ -144,6 +153,7 @@ public AbstractBuilder(DefaultTransportOptions options) {
144153
this.parameters = copyOrNull(options.parameters);
145154
this.onWarnings = options.onWarnings;
146155
this.keepResponseBodyOnException = options.keepResponseBodyOnException;
156+
this.enableServerlessMode = options.enableServerlessMode;
147157
}
148158

149159
protected abstract BuilderT self();
@@ -154,6 +164,12 @@ public BuilderT keepResponseBodyOnException(boolean value) {
154164
return self();
155165
}
156166

167+
@Override
168+
public BuilderT enableServerlessMode(boolean value) {
169+
this.enableServerlessMode = value;
170+
return self();
171+
}
172+
157173
@Override
158174
public BuilderT addHeader(String name, String value) {
159175
if (name.equalsIgnoreCase(HeaderMap.CLIENT_META)) {

java-client/src/main/java/co/elastic/clients/transport/ElasticsearchTransportBase.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,14 @@ public abstract class ElasticsearchTransportBase implements ElasticsearchTranspo
6565

6666
private static final String USER_AGENT_VALUE = getUserAgent();
6767
private static final String CLIENT_META_VALUE = getClientMeta();
68-
public static final String JSON_CONTENT_TYPE;
68+
public static final String JSON_CONTENT_TYPE_ES = "application/vnd.elasticsearch+json; compatible-with=" +
69+
Version.VERSION.major();
6970

70-
static {
71-
if (Version.VERSION == null) {
72-
JSON_CONTENT_TYPE = ContentType.APPLICATION_JSON;
71+
private String getContentTypeHeader() {
72+
if (Version.VERSION == null || options().enableServerlessMode()) {
73+
return ContentType.APPLICATION_JSON;
7374
} else {
74-
JSON_CONTENT_TYPE =
75-
"application/vnd.elasticsearch+json; compatible-with=" +
76-
Version.VERSION.major();
75+
return JSON_CONTENT_TYPE_ES;
7776
}
7877
}
7978

@@ -243,6 +242,9 @@ private <RequestT, ResponseT, ErrorT> TransportHttpClient.Request prepareTranspo
243242
Map<String, String> params = endpoint.queryParameters(request);
244243

245244
List<ByteBuffer> bodyBuffers = null;
245+
String contentTypeValue = getContentTypeHeader();
246+
DefaultHeaders.put(HeaderMap.ACCEPT,contentTypeValue);
247+
JsonContentTypeHeaders.put(HeaderMap.CONTENT_TYPE, contentTypeValue);
246248
HeaderMap headers = DefaultHeaders;
247249

248250
Object body = endpoint.body(request);
@@ -301,7 +303,6 @@ private <RequestT, ResponseT, ErrorT> TransportHttpClient.Request prepareTranspo
301303
static {
302304
addStandardHeaders(DefaultHeaders);
303305
addStandardHeaders(JsonContentTypeHeaders);
304-
JsonContentTypeHeaders.put(HeaderMap.CONTENT_TYPE, JSON_CONTENT_TYPE);
305306
}
306307

307308
private static final ByteBuffer NdJsonSeparator = ByteBuffer.wrap("\n".getBytes(StandardCharsets.UTF_8));
@@ -509,7 +510,6 @@ private void checkJsonContentType(
509510
private static void addStandardHeaders(HeaderMap headers) {
510511
headers.put(HeaderMap.USER_AGENT, USER_AGENT_VALUE);
511512
headers.put(HeaderMap.CLIENT_META, CLIENT_META_VALUE);
512-
headers.put(HeaderMap.ACCEPT, JSON_CONTENT_TYPE);
513513
}
514514

515515
private static String getUserAgent() {

java-client/src/main/java/co/elastic/clients/transport/ElasticsearchTransportConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ protected ElasticsearchTransportConfig build() {
217217
}
218218

219219
return config;
220-
};
220+
}
221221

222222
/**
223223
* Elasticsearch host location

java-client/src/main/java/co/elastic/clients/transport/TransportOptions.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public interface TransportOptions {
4747
*/
4848
boolean keepResponseBodyOnException();
4949

50+
boolean enableServerlessMode();
51+
5052
Builder toBuilder();
5153

5254
default TransportOptions with(Consumer<Builder> fn) {
@@ -75,5 +77,7 @@ interface Builder extends ObjectBuilder<TransportOptions> {
7577
* streamed by the http library.
7678
*/
7779
Builder keepResponseBodyOnException(boolean value);
80+
81+
Builder enableServerlessMode(boolean value);
7882
}
7983
}

java-client/src/main/java/co/elastic/clients/transport/http/HeaderMap.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public class HeaderMap extends AbstractMap<String, String> {
3636
public static final String CONTENT_TYPE = "Content-Type";
3737
public static final String USER_AGENT = "User-Agent";
3838
public static final String CLIENT_META = "X-Elastic-Client-Meta";
39+
public static final String SERVERLESS_META = "Elastic-Api-Version";
40+
public static final String SERVERLESS_META_VALUE = "2023-10-31";
3941

4042
@Nullable
4143
protected Map<String, String> map;

java-client/src/main/java/co/elastic/clients/transport/rest5_client/Rest5ClientOptions.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public class Rest5ClientOptions implements TransportOptions {
4444

4545
boolean keepResponseBodyOnException;
4646

47+
boolean enableServerlessMode;
48+
4749
@VisibleForTesting
4850
static final String CLIENT_META_VALUE = getClientMeta();
4951
@VisibleForTesting
@@ -62,14 +64,26 @@ public static Rest5ClientOptions of(@Nullable TransportOptions options) {
6264
options.headers().forEach(h -> builder.addHeader(h.getKey(), h.getValue()));
6365
options.queryParameters().forEach(builder::setParameter);
6466
builder.onWarnings(options.onWarnings());
67+
builder.keepResponseBodyOnException(options.keepResponseBodyOnException());
68+
builder.enableServerlessMode(options.enableServerlessMode());
6569
return builder.build();
6670
}
6771

72+
public Rest5ClientOptions(RequestOptions options) {
73+
this.options = addBuiltinHeaders(options.toBuilder()).build();
74+
}
75+
6876
public Rest5ClientOptions(RequestOptions options, boolean keepResponseBodyOnException) {
6977
this.keepResponseBodyOnException = keepResponseBodyOnException;
7078
this.options = addBuiltinHeaders(options.toBuilder()).build();
7179
}
7280

81+
public Rest5ClientOptions(RequestOptions options, boolean keepResponseBodyOnException, boolean enableServerlessMode) {
82+
this.keepResponseBodyOnException = keepResponseBodyOnException;
83+
this.enableServerlessMode = enableServerlessMode;
84+
this.options = addBuiltinHeaders(options.toBuilder()).build();
85+
}
86+
7387
/**
7488
* Get the wrapped Rest Client request options
7589
*/
@@ -112,6 +126,11 @@ public boolean keepResponseBodyOnException() {
112126
return this.keepResponseBodyOnException;
113127
}
114128

129+
@Override
130+
public boolean enableServerlessMode() {
131+
return this.enableServerlessMode;
132+
}
133+
115134
@Override
116135
public Builder toBuilder() {
117136
return new Builder(options.toBuilder());
@@ -123,6 +142,8 @@ public static class Builder implements TransportOptions.Builder {
123142

124143
private boolean keepResponseBodyOnException;
125144

145+
private boolean enableServerlessMode;
146+
126147
public Builder(RequestOptions.Builder builder) {
127148
this.builder = builder;
128149
}
@@ -202,9 +223,15 @@ public TransportOptions.Builder keepResponseBodyOnException(boolean value) {
202223
return this;
203224
}
204225

226+
@Override
227+
public TransportOptions.Builder enableServerlessMode(boolean value) {
228+
this.enableServerlessMode = value;
229+
return this;
230+
}
231+
205232
@Override
206233
public Rest5ClientOptions build() {
207-
return new Rest5ClientOptions(addBuiltinHeaders(builder).build(), keepResponseBodyOnException);
234+
return new Rest5ClientOptions(addBuiltinHeaders(builder).build(), keepResponseBodyOnException, enableServerlessMode);
208235
}
209236
}
210237

@@ -218,10 +245,6 @@ private static RequestOptions.Builder addBuiltinHeaders(RequestOptions.Builder b
218245
if (builder.getHeaders().stream().noneMatch(h -> h.getName().equalsIgnoreCase(HeaderMap.USER_AGENT))) {
219246
builder.addHeader(HeaderMap.USER_AGENT, USER_AGENT_VALUE);
220247
}
221-
if (builder.getHeaders().stream().noneMatch(h -> h.getName().equalsIgnoreCase(HeaderMap.ACCEPT))) {
222-
builder.addHeader(HeaderMap.ACCEPT, Rest5ClientTransport.JSON_CONTENT_TYPE);
223-
}
224-
225248
return builder;
226249
}
227250

java-client/src/main/java/co/elastic/clients/transport/rest5_client/Rest5ClientTransport.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@
2424
import co.elastic.clients.transport.Transport;
2525
import co.elastic.clients.transport.ElasticsearchTransportConfig;
2626
import co.elastic.clients.transport.TransportOptions;
27+
import co.elastic.clients.transport.http.HeaderMap;
2728
import co.elastic.clients.transport.instrumentation.Instrumentation;
2829
import co.elastic.clients.transport.rest5_client.low_level.Rest5Client;
2930
import co.elastic.clients.transport.rest5_client.low_level.Rest5ClientBuilder;
30-
import org.apache.hc.core5.http.Header;
3131
import org.apache.hc.core5.http.message.BasicHeader;
3232

3333
import javax.annotation.Nullable;
3434
import java.util.Base64;
35+
import java.util.HashMap;
36+
import java.util.Map;
3537

3638
public class Rest5ClientTransport extends ElasticsearchTransportBase {
3739

@@ -64,21 +66,30 @@ public Rest5ClientTransport(Rest5Client restClient, JsonpMapper jsonpMapper, Res
6466
private static Rest5Client buildRest5Client(ElasticsearchTransportConfig config) {
6567
Rest5ClientBuilder restClientBuilder = Rest5Client.builder(config.hosts());
6668

69+
Map<String, BasicHeader> defaultHeaders = new HashMap<>();
70+
6771
if (config.username() != null && config.password() != null) {
6872
var cred = Base64.getEncoder().encodeToString((config.username() + ":" + config.password()).getBytes());
69-
restClientBuilder.setDefaultHeaders(new Header[]{
70-
new BasicHeader("Authorization", "Basic " + cred)
71-
});
73+
defaultHeaders.putIfAbsent("Authorization", new BasicHeader("Authorization","Basic " + cred));
7274
} else if (config.apiKey() != null) {
73-
restClientBuilder.setDefaultHeaders(new Header[]{
74-
new BasicHeader("Authorization", "ApiKey " + config.apiKey())
75-
});
75+
defaultHeaders.putIfAbsent("Authorization", new BasicHeader("Authorization", "ApiKey " + config.apiKey()));
7676
} else if (config.token() != null) {
77-
restClientBuilder.setDefaultHeaders(new Header[]{
78-
new BasicHeader("Authorization", "Bearer " + config.token())
79-
});
77+
defaultHeaders.putIfAbsent("Authorization", new BasicHeader("Authorization", "Bearer " + config.token()));
78+
}
79+
80+
if (config.transportOptions() != null && config.transportOptions().enableServerlessMode()) {
81+
if (config.hosts().size() == 1 && config.hosts().get(0).getHost().endsWith("elastic.cloud")) {
82+
defaultHeaders.putIfAbsent(HeaderMap.SERVERLESS_META, new BasicHeader(HeaderMap.SERVERLESS_META,HeaderMap.SERVERLESS_META_VALUE));
83+
}
84+
else {
85+
throw new IllegalArgumentException(
86+
"If serverless mode is enabled, host must be a single serverless node"
87+
);
88+
}
8089
}
8190

91+
restClientBuilder.setDefaultHeaders(defaultHeaders.values().toArray(new BasicHeader[0]));
92+
8293
if (config.sslContext() != null) {
8394
restClientBuilder.setSSLContext(config.sslContext());
8495
}

0 commit comments

Comments
 (0)