From 86ba115f6a6af80639cd10f24a2355b11d43ab51 Mon Sep 17 00:00:00 2001 From: Dimitris Athanasiou Date: Wed, 4 Mar 2026 16:10:35 +0200 Subject: [PATCH 1/2] [Inference API] Handle empty date strings when parsing endpoint metadata heuristics This adds handling of blank date strings when parsing endpoint metadata heuristics by treating it as `null`. This could not occur in practice as EIS won't be serving empty strings. However, there are tests that pass in an empty string (e.g. callers of `createAuthorizedEndpoint` in `ElasticInferenceServiceAuthorizationResponseEntityTests` may lead to this case). Rather than change the tests, it makes more sense to make date parsing more robust. --- .../xpack/inference/common/parser/DateParser.java | 2 +- .../xpack/inference/common/parser/DateParserTests.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/common/parser/DateParser.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/common/parser/DateParser.java index b53319449a79d..77de84c719bdc 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/common/parser/DateParser.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/common/parser/DateParser.java @@ -24,7 +24,7 @@ public static LocalDate parseLocalDate(Map sourceMap, String key public static LocalDate parseLocalDate(String dateString, String key, String root) { try { - if (dateString == null) { + if (Strings.isNullOrBlank(dateString)) { return null; } return LocalDate.parse(dateString); diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/common/parser/DateParserTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/common/parser/DateParserTests.java index 71965e6bceeb4..a6f02a5abf10e 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/common/parser/DateParserTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/common/parser/DateParserTests.java @@ -71,6 +71,11 @@ public void testParseLocalDate_FromString_ReturnsNull_WhenNull() { assertThat(DateParser.parseLocalDate((String) null, KEY, ROOT), nullValue()); } + public void testParseLocalDate_FromString_ReturnsNull_WhenEmptyString() { + assertThat(DateParser.parseLocalDate("", KEY, ROOT), nullValue()); + assertThat(DateParser.parseLocalDate(" ", KEY, ROOT), nullValue()); + } + public void testParseLocalDate_FromString_Throws_WhenInvalidFormat() { var e = expectThrows(IllegalArgumentException.class, () -> DateParser.parseLocalDate(INVALID_DATE_FORMAT, KEY, ROOT)); assertThat(e.getMessage(), containsString(pathToKey(ROOT, KEY))); From 1bf646ca824dfc4c41ec556b77988576a689fad7 Mon Sep 17 00:00:00 2001 From: Dimitris Athanasiou Date: Wed, 4 Mar 2026 17:27:30 +0200 Subject: [PATCH 2/2] Fix tests --- ...ferenceServiceAuthorizationModelTests.java | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/authorization/ElasticInferenceServiceAuthorizationModelTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/authorization/ElasticInferenceServiceAuthorizationModelTests.java index d6a4687b86af2..391ded499f128 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/authorization/ElasticInferenceServiceAuthorizationModelTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/services/elastic/authorization/ElasticInferenceServiceAuthorizationModelTests.java @@ -1026,15 +1026,15 @@ public void testHandlesNullDatesInHeuristics() { } public void testFiltersEndpointsWithInvalidReleaseDate() { - var id1 = "id1"; - var invalidId = "invalid_id"; - var invalidId2 = "invalid_id2"; + var validDateId = "valid_date_id"; + var blankDateId = "blank_date_id"; + var invalidDateId = "invalid_date_id"; var status = STATUS_GA; var response = new ElasticInferenceServiceAuthorizationResponseEntity( List.of( new ElasticInferenceServiceAuthorizationResponseEntity.AuthorizedEndpoint( - id1, + validDateId, "name1", createTaskTypeObject(EIS_CHAT_PATH, TaskType.CHAT_COMPLETION.toString()), status, @@ -1046,7 +1046,7 @@ public void testFiltersEndpointsWithInvalidReleaseDate() { null ), new ElasticInferenceServiceAuthorizationResponseEntity.AuthorizedEndpoint( - invalidId, + invalidDateId, "name2", createTaskTypeObject(EIS_CHAT_PATH, TaskType.CHAT_COMPLETION.toString()), status, @@ -1058,13 +1058,13 @@ public void testFiltersEndpointsWithInvalidReleaseDate() { null ), new ElasticInferenceServiceAuthorizationResponseEntity.AuthorizedEndpoint( - invalidId2, + blankDateId, "name3", createTaskTypeObject(EIS_CHAT_PATH, TaskType.CHAT_COMPLETION.toString()), status, null, - TEST_RELEASE_DATE, - "", + " ", + null, null, null, null @@ -1073,19 +1073,20 @@ public void testFiltersEndpointsWithInvalidReleaseDate() { ); var auth = ElasticInferenceServiceAuthorizationModel.of(response, "url"); - assertThat(auth.getEndpointIds(), is(Set.of(id1))); + assertThat(auth.getEndpointIds(), is(Set.of(validDateId, blankDateId))); assertTrue(auth.isAuthorized()); } public void testFiltersEndpointsWithInvalidEndOfLifeDate() { - var id1 = "id1"; - var invalidId = "invalid_id"; + var validDateId = "valid_date_id"; + var invalidDateId = "invalid_date_id"; + var blankDateId = "blank_date_id"; var status = STATUS_GA; var response = new ElasticInferenceServiceAuthorizationResponseEntity( List.of( new ElasticInferenceServiceAuthorizationResponseEntity.AuthorizedEndpoint( - id1, + validDateId, "name1", createTaskTypeObject(EIS_CHAT_PATH, TaskType.CHAT_COMPLETION.toString()), status, @@ -1097,22 +1098,34 @@ public void testFiltersEndpointsWithInvalidEndOfLifeDate() { null ), new ElasticInferenceServiceAuthorizationResponseEntity.AuthorizedEndpoint( - invalidId, + invalidDateId, "name2", createTaskTypeObject(EIS_CHAT_PATH, TaskType.CHAT_COMPLETION.toString()), status, null, - "", + TEST_RELEASE_DATE, "invalid-date-format", null, null, null + ), + new ElasticInferenceServiceAuthorizationResponseEntity.AuthorizedEndpoint( + blankDateId, + "name2", + createTaskTypeObject(EIS_CHAT_PATH, TaskType.CHAT_COMPLETION.toString()), + status, + null, + TEST_RELEASE_DATE, + " ", + null, + null, + null ) ) ); var auth = ElasticInferenceServiceAuthorizationModel.of(response, "url"); - assertThat(auth.getEndpointIds(), is(Set.of(id1))); + assertThat(auth.getEndpointIds(), is(Set.of(validDateId, blankDateId))); assertTrue(auth.isAuthorized()); }