Skip to content

Commit ee20dbb

Browse files
fix(prefix): improve/fix es prefix calculation (#15110)
1 parent bc25b82 commit ee20dbb

File tree

6 files changed

+116
-121
lines changed

6 files changed

+116
-121
lines changed

datahub-upgrade/src/main/java/com/linkedin/datahub/upgrade/system/elasticsearch/steps/CreateUsageEventIndicesStep.java

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.linkedin.datahub.upgrade.UpgradeStep;
55
import com.linkedin.datahub.upgrade.UpgradeStepResult;
66
import com.linkedin.datahub.upgrade.impl.DefaultUpgradeStepResult;
7-
import com.linkedin.datahub.upgrade.system.elasticsearch.util.IndexUtils;
87
import com.linkedin.datahub.upgrade.system.elasticsearch.util.UsageEventIndexUtils;
98
import com.linkedin.gms.factory.config.ConfigurationProvider;
109
import com.linkedin.gms.factory.search.BaseElasticSearchComponentsFactory;
@@ -44,11 +43,8 @@ public Function<UpgradeContext, UpgradeStepResult> executable() {
4443
return (context) -> {
4544
try {
4645

47-
String indexPrefix = configurationProvider.getElasticSearch().getIndex().getPrefix();
48-
// Handle null prefix by converting to empty string
49-
if (indexPrefix == null) {
50-
indexPrefix = "";
51-
}
46+
final String indexPrefix =
47+
configurationProvider.getElasticSearch().getIndex().getFinalPrefix();
5248

5349
boolean useOpenSearch = esComponents.getSearchClient().getEngineType().isOpenSearch();
5450
int numShards = esComponents.getIndexBuilder().getNumShards();
@@ -70,10 +66,9 @@ public Function<UpgradeContext, UpgradeStepResult> executable() {
7066

7167
private void setupElasticsearchUsageEvents(String prefix, int numShards, int numReplicas)
7268
throws Exception {
73-
String prefixedPolicy = IndexUtils.createPrefixedName(prefix, "datahub_usage_event_policy");
74-
String prefixedTemplate =
75-
IndexUtils.createPrefixedName(prefix, "datahub_usage_event_index_template");
76-
String prefixedDataStream = IndexUtils.createPrefixedName(prefix, "datahub_usage_event");
69+
String prefixedPolicy = prefix + "datahub_usage_event_policy";
70+
String prefixedTemplate = prefix + "datahub_usage_event_index_template";
71+
String prefixedDataStream = prefix + "datahub_usage_event";
7772

7873
// Create ILM policy
7974
UsageEventIndexUtils.createIlmPolicy(esComponents, prefixedPolicy);
@@ -89,10 +84,9 @@ private void setupElasticsearchUsageEvents(String prefix, int numShards, int num
8984
private void setupOpenSearchUsageEvents(
9085
String prefix, int numShards, int numReplicas, OperationContext operationContext)
9186
throws Exception {
92-
String prefixedPolicy = IndexUtils.createPrefixedName(prefix, "datahub_usage_event_policy");
93-
String prefixedTemplate =
94-
IndexUtils.createPrefixedName(prefix, "datahub_usage_event_index_template");
95-
String prefixedIndex = IndexUtils.createPrefixedName(prefix, "datahub_usage_event-000001");
87+
String prefixedPolicy = prefix + "datahub_usage_event_policy";
88+
String prefixedTemplate = prefix + "datahub_usage_event_index_template";
89+
String prefixedIndex = prefix + "datahub_usage_event-000001";
9690

9791
// Create ISM policy (both AWS and self-hosted OpenSearch use the same format)
9892
boolean policyCreated =

datahub-upgrade/src/main/java/com/linkedin/datahub/upgrade/system/elasticsearch/util/IndexUtils.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -145,25 +145,6 @@ static int extractJsonValue(OperationContext operationContext, String json, Stri
145145
return -1;
146146
}
147147

148-
/**
149-
* Creates a prefixed name for usage event resources.
150-
*
151-
* <p>This method handles the logic for adding prefixes to usage event resource names, including
152-
* the proper separator handling. If the prefix is empty, no separator is added. If the prefix is
153-
* not empty, an underscore separator is added between the prefix and the resource name.
154-
*
155-
* @param prefix the index prefix (e.g., "prod", "dev", or empty string)
156-
* @param resourceName the base resource name (e.g., "datahub_usage_event_policy")
157-
* @return the prefixed resource name (e.g., "prod_datahub_usage_event_policy" or
158-
* "datahub_usage_event_policy")
159-
*/
160-
public static String createPrefixedName(String prefix, String resourceName) {
161-
if (prefix == null || prefix.isEmpty()) {
162-
return resourceName;
163-
}
164-
return prefix + "_" + resourceName;
165-
}
166-
167148
/**
168149
* Loads a resource file as a UTF-8 encoded string.
169150
*

datahub-upgrade/src/test/java/com/linkedin/datahub/upgrade/system/elasticsearch/steps/CreateUsageEventIndicesStepTest.java

Lines changed: 14 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.linkedin.datahub.upgrade.system.elasticsearch.steps;
22

3+
import static org.mockito.Mockito.atLeastOnce;
4+
35
import com.linkedin.datahub.upgrade.UpgradeContext;
46
import com.linkedin.datahub.upgrade.UpgradeStepResult;
57
import com.linkedin.gms.factory.config.ConfigurationProvider;
@@ -60,7 +62,7 @@ public void setUp() throws IOException {
6062
Mockito.when(configurationProvider.getPlatformAnalytics()).thenReturn(platformAnalytics);
6163
Mockito.when(configurationProvider.getElasticSearch()).thenReturn(elasticSearch);
6264
Mockito.when(elasticSearch.getIndex()).thenReturn(index);
63-
Mockito.when(index.getPrefix()).thenReturn("test_");
65+
Mockito.when(index.getFinalPrefix()).thenReturn("test_");
6466

6567
Mockito.when(upgradeContext.opContext()).thenReturn(opContext);
6668

@@ -279,7 +281,7 @@ public void testExecutable_WithEmptyPrefix() throws Exception {
279281
// Arrange
280282
Mockito.when(platformAnalytics.isEnabled()).thenReturn(true);
281283
Mockito.when(searchEngineType.isOpenSearch()).thenReturn(false);
282-
Mockito.when(index.getPrefix()).thenReturn(""); // Empty prefix
284+
Mockito.when(index.getFinalPrefix()).thenReturn(""); // Empty prefix
283285

284286
// Act
285287
Function<UpgradeContext, UpgradeStepResult> executable = step.executable();
@@ -291,44 +293,7 @@ public void testExecutable_WithEmptyPrefix() throws Exception {
291293
Assert.assertEquals(result.result(), DataHubUpgradeState.SUCCEEDED);
292294

293295
// Verify empty prefix was used and no underscore separator was added
294-
Mockito.verify(index).getPrefix();
295-
296-
// Verify that the low-level requests were made with correct names (no underscore prefix)
297-
Mockito.verify(searchClient, Mockito.atLeast(2)).performLowLevelRequest(Mockito.any());
298-
299-
// Verify specific endpoint calls were made
300-
Mockito.verify(searchClient)
301-
.performLowLevelRequest(
302-
Mockito.argThat(
303-
request ->
304-
request.getEndpoint().equals("/_ilm/policy/datahub_usage_event_policy")));
305-
Mockito.verify(searchClient)
306-
.performLowLevelRequest(
307-
Mockito.argThat(
308-
request ->
309-
request
310-
.getEndpoint()
311-
.equals("/_index_template/datahub_usage_event_index_template")));
312-
}
313-
314-
@Test
315-
public void testExecutable_WithNullPrefix() throws Exception {
316-
// Arrange
317-
Mockito.when(platformAnalytics.isEnabled()).thenReturn(true);
318-
Mockito.when(searchEngineType.isOpenSearch()).thenReturn(false);
319-
Mockito.when(index.getPrefix()).thenReturn(null); // Null prefix
320-
321-
// Act
322-
Function<UpgradeContext, UpgradeStepResult> executable = step.executable();
323-
UpgradeStepResult result = executable.apply(upgradeContext);
324-
325-
// Assert
326-
Assert.assertNotNull(result);
327-
Assert.assertEquals(result.stepId(), "CreateUsageEventIndicesStep");
328-
Assert.assertEquals(result.result(), DataHubUpgradeState.SUCCEEDED);
329-
330-
// Verify null prefix was handled and no underscore separator was added
331-
Mockito.verify(index).getPrefix();
296+
Mockito.verify(index, atLeastOnce()).getFinalPrefix();
332297

333298
// Verify that the low-level requests were made with correct names (no underscore prefix)
334299
Mockito.verify(searchClient, Mockito.atLeast(2)).performLowLevelRequest(Mockito.any());
@@ -353,7 +318,7 @@ public void testExecutable_WithNonEmptyPrefix() throws Exception {
353318
// Arrange
354319
Mockito.when(platformAnalytics.isEnabled()).thenReturn(true);
355320
Mockito.when(searchEngineType.isOpenSearch()).thenReturn(false);
356-
Mockito.when(index.getPrefix()).thenReturn("prod"); // Non-empty prefix
321+
Mockito.when(index.getFinalPrefix()).thenReturn("prod_"); // Non-empty prefix
357322

358323
// Act
359324
Function<UpgradeContext, UpgradeStepResult> executable = step.executable();
@@ -365,7 +330,7 @@ public void testExecutable_WithNonEmptyPrefix() throws Exception {
365330
Assert.assertEquals(result.result(), DataHubUpgradeState.SUCCEEDED);
366331

367332
// Verify non-empty prefix was used and underscore separator was added
368-
Mockito.verify(index).getPrefix();
333+
Mockito.verify(index, atLeastOnce()).getFinalPrefix();
369334

370335
// Verify that the low-level requests were made with correct names (with underscore prefix)
371336
Mockito.verify(searchClient)
@@ -387,8 +352,8 @@ public void testExecutable_WithSpecificPrefix() throws Exception {
387352
// Arrange
388353
Mockito.when(platformAnalytics.isEnabled()).thenReturn(true);
389354
Mockito.when(searchEngineType.isOpenSearch()).thenReturn(false);
390-
Mockito.when(index.getPrefix())
391-
.thenReturn("kbcpyv7ss3-staging-test"); // Specific prefix from issue
355+
Mockito.when(index.getFinalPrefix())
356+
.thenReturn("kbcpyv7ss3-staging-test_"); // Specific prefix from issue
392357

393358
// Act
394359
Function<UpgradeContext, UpgradeStepResult> executable = step.executable();
@@ -400,7 +365,7 @@ public void testExecutable_WithSpecificPrefix() throws Exception {
400365
Assert.assertEquals(result.result(), DataHubUpgradeState.SUCCEEDED);
401366

402367
// Verify specific prefix was used and underscore separator was added
403-
Mockito.verify(index).getPrefix();
368+
Mockito.verify(index, atLeastOnce()).getFinalPrefix();
404369

405370
// Verify that the low-level requests were made with correct names (with underscore prefix)
406371
Mockito.verify(searchClient)
@@ -426,7 +391,7 @@ public void testExecutable_OpenSearchPath_WithEmptyPrefix() throws Exception {
426391
// Arrange
427392
Mockito.when(platformAnalytics.isEnabled()).thenReturn(true);
428393
Mockito.when(searchEngineType.isOpenSearch()).thenReturn(true);
429-
Mockito.when(index.getPrefix()).thenReturn(""); // Empty prefix
394+
Mockito.when(index.getFinalPrefix()).thenReturn(""); // Empty prefix
430395

431396
// Act
432397
Function<UpgradeContext, UpgradeStepResult> executable = step.executable();
@@ -439,7 +404,7 @@ public void testExecutable_OpenSearchPath_WithEmptyPrefix() throws Exception {
439404

440405
// Verify OpenSearch path was taken and empty prefix was used
441406
Mockito.verify(searchEngineType).isOpenSearch();
442-
Mockito.verify(index).getPrefix();
407+
Mockito.verify(index, atLeastOnce()).getFinalPrefix();
443408

444409
// Verify that the low-level requests were made with correct names (no underscore prefix)
445410
// Note: createIsmPolicy makes 2 calls - one for creation and one for update attempt
@@ -464,7 +429,7 @@ public void testExecutable_OpenSearchPath_WithNonEmptyPrefix() throws Exception
464429
// Arrange
465430
Mockito.when(platformAnalytics.isEnabled()).thenReturn(true);
466431
Mockito.when(searchEngineType.isOpenSearch()).thenReturn(true);
467-
Mockito.when(index.getPrefix()).thenReturn("prod"); // Non-empty prefix
432+
Mockito.when(index.getFinalPrefix()).thenReturn("prod_"); // Non-empty prefix
468433

469434
// Act
470435
Function<UpgradeContext, UpgradeStepResult> executable = step.executable();
@@ -477,7 +442,7 @@ public void testExecutable_OpenSearchPath_WithNonEmptyPrefix() throws Exception
477442

478443
// Verify OpenSearch path was taken and non-empty prefix was used
479444
Mockito.verify(searchEngineType).isOpenSearch();
480-
Mockito.verify(index).getPrefix();
445+
Mockito.verify(index, atLeastOnce()).getFinalPrefix();
481446

482447
// Verify that the low-level requests were made with correct names (with underscore prefix)
483448
// Note: createIsmPolicy makes 2 calls - one for creation and one for update attempt

datahub-upgrade/src/test/java/com/linkedin/datahub/upgrade/system/elasticsearch/util/IndexUtilsTest.java

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,6 @@ public void setUp() {
3131
Mockito.when(operationContext.getObjectMapper()).thenReturn(objectMapper);
3232
}
3333

34-
@Test
35-
public void testCreatePrefixedName_WithPrefix() {
36-
// Arrange
37-
String prefix = "test";
38-
String resourceName = "index";
39-
40-
// Act
41-
String result = IndexUtils.createPrefixedName(prefix, resourceName);
42-
43-
// Assert
44-
Assert.assertEquals(result, "test_index");
45-
}
46-
47-
@Test
48-
public void testCreatePrefixedName_EmptyPrefix() {
49-
// Arrange
50-
String prefix = "";
51-
String resourceName = "index";
52-
53-
// Act
54-
String result = IndexUtils.createPrefixedName(prefix, resourceName);
55-
56-
// Assert
57-
Assert.assertEquals(result, "index");
58-
}
59-
60-
@Test
61-
public void testCreatePrefixedName_NullPrefix() {
62-
// Arrange
63-
String prefix = null;
64-
String resourceName = "index";
65-
66-
// Act
67-
String result = IndexUtils.createPrefixedName(prefix, resourceName);
68-
69-
// Assert
70-
Assert.assertEquals(result, "index");
71-
}
72-
7334
@Test
7435
public void testIsAwsOpenSearchService_AwsHost() {
7536
// Arrange

metadata-service/configuration/src/main/java/com/linkedin/metadata/config/search/IndexConfiguration.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@ public class IndexConfiguration {
77
private String prefix;
88
private DocIdsConfiguration docIds;
99
private Integer minSearchFilterLength;
10+
11+
public String getFinalPrefix() {
12+
if (prefix == null || prefix.isEmpty()) {
13+
return "";
14+
} else {
15+
return prefix + "_";
16+
}
17+
}
1018
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.linkedin.metadata.config.search;
2+
3+
import org.testng.Assert;
4+
import org.testng.annotations.Test;
5+
6+
public class IndexConfigurationTest {
7+
8+
@Test
9+
public void testGetFinalPrefix_WithPrefix() {
10+
// Arrange
11+
IndexConfiguration config = new IndexConfiguration();
12+
config.setPrefix("prod");
13+
14+
// Act
15+
String result = config.getFinalPrefix();
16+
17+
// Assert
18+
Assert.assertEquals(result, "prod_");
19+
}
20+
21+
@Test
22+
public void testGetFinalPrefix_EmptyPrefix() {
23+
// Arrange
24+
IndexConfiguration config = new IndexConfiguration();
25+
config.setPrefix("");
26+
27+
// Act
28+
String result = config.getFinalPrefix();
29+
30+
// Assert
31+
Assert.assertEquals(result, "");
32+
}
33+
34+
@Test
35+
public void testGetFinalPrefix_NullPrefix() {
36+
// Arrange
37+
IndexConfiguration config = new IndexConfiguration();
38+
config.setPrefix(null);
39+
40+
// Act
41+
String result = config.getFinalPrefix();
42+
43+
// Assert
44+
Assert.assertEquals(result, "");
45+
}
46+
47+
@Test
48+
public void testGetFinalPrefix_DefaultConstructor() {
49+
// Arrange
50+
IndexConfiguration config = new IndexConfiguration();
51+
// prefix is null by default
52+
53+
// Act
54+
String result = config.getFinalPrefix();
55+
56+
// Assert
57+
Assert.assertEquals(result, "");
58+
}
59+
60+
@Test
61+
public void testGetFinalPrefix_WithComplexPrefix() {
62+
// Arrange
63+
IndexConfiguration config = new IndexConfiguration();
64+
config.setPrefix("kbcpyv7ss3-staging-test");
65+
66+
// Act
67+
String result = config.getFinalPrefix();
68+
69+
// Assert
70+
Assert.assertEquals(result, "kbcpyv7ss3-staging-test_");
71+
}
72+
73+
@Test
74+
public void testGetFinalPrefix_WithWhitespacePrefix() {
75+
// Arrange
76+
IndexConfiguration config = new IndexConfiguration();
77+
config.setPrefix(" ");
78+
79+
// Act
80+
String result = config.getFinalPrefix();
81+
82+
// Assert
83+
// Whitespace-only string is not considered empty by isEmpty()
84+
Assert.assertEquals(result, " _");
85+
}
86+
}

0 commit comments

Comments
 (0)