Skip to content

Commit 39168e1

Browse files
authored
[EIS] Validate EIS Gateway URL if set (#114600)
1 parent f8074f4 commit 39168e1

File tree

5 files changed

+152
-3
lines changed

5 files changed

+152
-3
lines changed

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceSettings.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,65 @@
77

88
package org.elasticsearch.xpack.inference.services.elastic;
99

10+
import org.apache.logging.log4j.LogManager;
11+
import org.apache.logging.log4j.Logger;
1012
import org.elasticsearch.common.settings.Setting;
1113
import org.elasticsearch.common.settings.Settings;
1214

15+
import java.net.URI;
16+
import java.net.URISyntaxException;
1317
import java.util.List;
18+
import java.util.Objects;
19+
import java.util.Set;
1420

21+
/**
22+
* Class encapsulating any global setting for the EIS integration.
23+
*/
1524
public class ElasticInferenceServiceSettings {
1625

17-
static final Setting<String> EIS_GATEWAY_URL = Setting.simpleString("xpack.inference.eis.gateway.url", Setting.Property.NodeScope);
26+
public static final Setting<String> EIS_GATEWAY_URL = Setting.simpleString(
27+
"xpack.inference.eis.gateway.url",
28+
new EisGatewayURLValidator(),
29+
Setting.Property.NodeScope
30+
);
31+
32+
private static final Logger log = LogManager.getLogger(ElasticInferenceServiceSettings.class);
33+
34+
/**
35+
* Class to validate the EIS Gateway url set via `xpack.inference.eis.gateway.url`.
36+
*/
37+
public static class EisGatewayURLValidator implements Setting.Validator<String> {
38+
39+
private static final Set<String> VALID_EIS_GATEWAY_SCHEMES = Set.of("http", "https");
40+
41+
@Override
42+
public void validate(String value) {
43+
if (Objects.isNull(value) || value.isEmpty()) {
44+
// No validation needed, if eis-gateway URL is not set
45+
log.debug("eis-gateway url not set. Skipping validation");
46+
return;
47+
}
48+
49+
try {
50+
var uri = new URI(value);
51+
var scheme = uri.getScheme();
52+
53+
if (scheme == null || VALID_EIS_GATEWAY_SCHEMES.contains(scheme) == false) {
54+
throw new IllegalArgumentException(
55+
"["
56+
+ scheme
57+
+ "] is not a valid URI scheme for the setting ["
58+
+ ElasticInferenceServiceSettings.EIS_GATEWAY_URL.getKey()
59+
+ "]. Use one of ["
60+
+ String.join(",", VALID_EIS_GATEWAY_SCHEMES)
61+
+ "]"
62+
);
63+
}
64+
} catch (URISyntaxException e) {
65+
throw new IllegalArgumentException("[" + e.getInput() + "] is not a valid URI", e);
66+
}
67+
}
68+
}
1869

1970
// Adjust this variable to be volatile, if the setting can be updated at some point in time
2071
private final String eisGatewayUrl;

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceSparseEmbeddingsModel.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ private URI createUri() throws URISyntaxException {
108108
default -> throw new IllegalArgumentException("Unsupported model for EIS [" + modelId + "]");
109109
}
110110

111-
return new URI(elasticInferenceServiceComponents().eisGatewayUrl() + "/sparse-text-embedding/" + modelIdUriPath);
111+
var uriString = elasticInferenceServiceComponents().eisGatewayUrl() + "/sparse-text-embedding/" + modelIdUriPath;
112+
113+
// We perform the same validation here as when reading the setting to make sure that our extended URI is still valid
114+
// This method throws, if the URI is invalid
115+
new ElasticInferenceServiceSettings.EisGatewayURLValidator().validate(uriString);
116+
117+
return new URI(uriString);
112118
}
113119
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.inference.services.elastic;
9+
10+
import org.elasticsearch.test.ESTestCase;
11+
12+
public class ElasticInferenceServiceSettingsTests extends ESTestCase {
13+
14+
public void testEisGatewayURLValidator_Validate_ThrowError_OnMissingURIScheme() {
15+
expectThrows(
16+
IllegalArgumentException.class,
17+
() -> new ElasticInferenceServiceSettings.EisGatewayURLValidator().validate("www.missing-scheme-gateway-url.com")
18+
);
19+
}
20+
21+
public void testEisGatewayURLValidator_Validate_ThrowError_OnWrongURIScheme() {
22+
expectThrows(
23+
IllegalArgumentException.class,
24+
() -> new ElasticInferenceServiceSettings.EisGatewayURLValidator().validate("file://www.missing-scheme-gateway-url.com")
25+
);
26+
}
27+
28+
public void testEisGatewayURLValidator_Validate_DoesNotThrowError_ForHTTP() {
29+
var scheme = "http";
30+
31+
try {
32+
new ElasticInferenceServiceSettings.EisGatewayURLValidator().validate(scheme + "://www.valid-gateway-url.com");
33+
} catch (Exception e) {
34+
fail(e, "Should not throw exception for " + "[" + scheme + "]");
35+
}
36+
}
37+
38+
public void testEisGatewayURLValidator_Validate_DoesNotThrowError_ForHTTPS() {
39+
var scheme = "https";
40+
41+
try {
42+
new ElasticInferenceServiceSettings.EisGatewayURLValidator().validate(scheme + "://www.valid-gateway-url.com");
43+
} catch (Exception e) {
44+
fail(e, "Should not throw exception for " + "[" + scheme + "]");
45+
}
46+
}
47+
48+
public void testEisGatewayURLValidator_Validate_DoesNotThrowError_IfURLNull() {
49+
try {
50+
new ElasticInferenceServiceSettings.EisGatewayURLValidator().validate(null);
51+
} catch (Exception e) {
52+
fail(e, "Should not throw exception for, if eis-gateway URL is null");
53+
}
54+
}
55+
56+
public void testEisGatewayURLValidator_Validate_DoesNotThrowError_IfURLEmpty() {
57+
try {
58+
new ElasticInferenceServiceSettings.EisGatewayURLValidator().validate("");
59+
} catch (Exception e) {
60+
fail(e, "Should not throw exception for, if eis-gateway URL is empty");
61+
}
62+
}
63+
64+
}

x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceSparseEmbeddingsModelTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,34 @@
1515

1616
public class ElasticInferenceServiceSparseEmbeddingsModelTests extends ESTestCase {
1717

18+
public void testCreateURI_ThrowError_OnMissingURIScheme() {
19+
expectThrows(IllegalArgumentException.class, () -> createModel("www.missing-scheme-gateway-url.com"));
20+
}
21+
22+
public void testCreateURI_ThrowError_OnWrongURIScheme() {
23+
expectThrows(IllegalArgumentException.class, () -> createModel("file://www.missing-scheme-gateway-url.com"));
24+
}
25+
26+
public void testCreateURI_DoesNotThrowError_ForHTTP() {
27+
var scheme = "http";
28+
29+
try {
30+
createModel(scheme + "://www.valid-gateway-url.com");
31+
} catch (Exception e) {
32+
fail(e, "Should not throw exception for " + "[" + scheme + "]");
33+
}
34+
}
35+
36+
public void testCreateURI_DoesNotThrowError_ForHTTPS() {
37+
var scheme = "https";
38+
39+
try {
40+
createModel(scheme + "://www.valid-gateway-url.com");
41+
} catch (Exception e) {
42+
fail(e, "Should not throw exception for " + "[" + scheme + "]");
43+
}
44+
}
45+
1846
public static ElasticInferenceServiceSparseEmbeddingsModel createModel(String url) {
1947
return createModel(url, null);
2048
}

x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ private ElasticInferenceService createServiceWithMockSender() {
492492
return new ElasticInferenceService(
493493
mock(HttpRequestSender.Factory.class),
494494
createWithEmptySettings(threadPool),
495-
new ElasticInferenceServiceComponents(null)
495+
new ElasticInferenceServiceComponents("http://valid-eis-gateway-url.com")
496496
);
497497
}
498498
}

0 commit comments

Comments
 (0)