Skip to content

Commit 4d9160f

Browse files
ruai0511tandonks
authored andcommitted
Bug fix and logging improvements for auto tagging (opensearch-project#18726)
Signed-off-by: Ruirui Zhang <mariazrr@amazon.com>
1 parent d263a25 commit 4d9160f

File tree

9 files changed

+74
-16
lines changed

9 files changed

+74
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
2323
- Add BooleanQuery rewrite moving constant-scoring must clauses to filter clauses ([#18510](https://github.com/opensearch-project/OpenSearch/issues/18510))
2424
- Add functionality for plugins to inject QueryCollectorContext during QueryPhase ([#18637](https://github.com/opensearch-project/OpenSearch/pull/18637))
2525
- Add support for non-timing info in profiler ([#18460](https://github.com/opensearch-project/OpenSearch/issues/18460))
26+
- [Rule-based auto tagging] Bug fix and improvements ([#18726](https://github.com/opensearch-project/OpenSearch/pull/18726))
2627
- Extend Approximation Framework to other numeric types ([#18530](https://github.com/opensearch-project/OpenSearch/issues/18530))
2728
- Add Semantic Version field type mapper and extensive unit tests([#18454](https://github.com/opensearch-project/OpenSearch/pull/18454))
2829
- Pass index settings to system ingest processor factories. ([#18708](https://github.com/opensearch-project/OpenSearch/pull/18708))

modules/autotagging-commons/common/src/main/java/org/opensearch/rule/action/CreateRuleRequest.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,7 @@ public CreateRuleRequest(StreamInput in) throws IOException {
4949

5050
@Override
5151
public ActionRequestValidationException validate() {
52-
try {
53-
rule.getFeatureType().getFeatureValueValidator().validate(rule.getFeatureValue());
54-
return null;
55-
} catch (Exception e) {
56-
ActionRequestValidationException validationException = new ActionRequestValidationException();
57-
validationException.addValidationError("Validation failed: " + e.getMessage());
58-
return validationException;
59-
}
52+
return null;
6053
}
6154

6255
@Override

modules/autotagging-commons/common/src/main/java/org/opensearch/rule/autotagging/RuleValidator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ private List<String> validateFeatureType() {
114114
if (featureType == null) {
115115
return List.of("Couldn't identify which feature the rule belongs to. Rule feature can't be null.");
116116
}
117+
try {
118+
featureType.getFeatureValueValidator().validate(featureValue);
119+
} catch (Exception e) {
120+
return List.of(e.getMessage());
121+
}
117122
return new ArrayList<>();
118123
}
119124

modules/autotagging-commons/common/src/main/java/org/opensearch/rule/service/IndexStoredRulePersistenceService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.opensearch.action.index.IndexRequest;
1717
import org.opensearch.action.search.SearchRequestBuilder;
1818
import org.opensearch.action.search.SearchResponse;
19+
import org.opensearch.action.support.WriteRequest;
1920
import org.opensearch.action.support.clustermanager.AcknowledgedResponse;
2021
import org.opensearch.action.update.UpdateRequest;
2122
import org.opensearch.cluster.service.ClusterService;
@@ -183,6 +184,7 @@ public void onFailure(Exception e) {
183184
private void persistRule(Rule rule, ActionListener<CreateRuleResponse> listener) {
184185
try {
185186
IndexRequest indexRequest = new IndexRequest(indexName).id(rule.getId())
187+
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
186188
.source(rule.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS));
187189
client.index(indexRequest).get();
188190
listener.onResponse(new CreateRuleResponse(rule));
@@ -312,9 +314,8 @@ public void onFailure(Exception e) {
312314
*/
313315
private void persistUpdatedRule(String ruleId, Rule updatedRule, ActionListener<UpdateRuleResponse> listener) {
314316
try {
315-
UpdateRequest updateRequest = new UpdateRequest(indexName, ruleId).doc(
316-
updatedRule.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS)
317-
);
317+
UpdateRequest updateRequest = new UpdateRequest(indexName, ruleId).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
318+
.doc(updatedRule.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS));
318319
client.update(updateRequest).get();
319320
listener.onResponse(new UpdateRuleResponse(updatedRule));
320321
} catch (Exception e) {

modules/autotagging-commons/common/src/test/java/org/opensearch/rule/autotagging/RuleValidatorTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import static org.opensearch.rule.autotagging.RuleTests.TestAttribute.TEST_ATTRIBUTE_1;
2424
import static org.opensearch.rule.autotagging.RuleTests.UPDATED_AT;
2525
import static org.opensearch.rule.autotagging.RuleTests._ID;
26+
import static org.mockito.Mockito.doThrow;
27+
import static org.mockito.Mockito.mock;
28+
import static org.mockito.Mockito.when;
2629

2730
public class RuleValidatorTests extends OpenSearchTestCase {
2831

@@ -118,4 +121,14 @@ public void testEqualRuleValidators() {
118121
RuleValidator otherValidator = new RuleValidator(_ID, DESCRIPTION, ATTRIBUTE_MAP, FEATURE_VALUE, UPDATED_AT, FEATURE_TYPE);
119122
assertEquals(validator, otherValidator);
120123
}
124+
125+
public void testFeatureValueValidationThrows() {
126+
FeatureType mockFeatureType = mock(FeatureType.class);
127+
FeatureValueValidator mockValidator = mock(FeatureValueValidator.class);
128+
when(mockFeatureType.getFeatureValueValidator()).thenReturn(mockValidator);
129+
doThrow(new IllegalArgumentException("Invalid feature value")).when(mockValidator).validate("bad-value");
130+
RuleValidator validator = new RuleValidator(_ID, DESCRIPTION, ATTRIBUTE_MAP, "bad-value", UPDATED_AT, mockFeatureType);
131+
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, validator::validate);
132+
assertTrue(ex.getMessage().contains("Invalid feature value"));
133+
}
121134
}

modules/autotagging-commons/src/main/java/org/opensearch/rule/rest/RestGetRuleAction.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,12 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
7474
}
7575

7676
final FeatureType featureType = FeatureType.from(request.param(FEATURE_TYPE));
77-
final Set<String> excludedKeys = Set.of(FEATURE_TYPE, ID_STRING, SEARCH_AFTER_STRING, "pretty");
78-
final List<String> requestParams = request.params().keySet().stream().filter(key -> !excludedKeys.contains(key)).toList();
79-
80-
for (String attributeName : requestParams) {
77+
final List<String> attributeParams = request.params()
78+
.keySet()
79+
.stream()
80+
.filter(key -> featureType.getAllowedAttributesRegistry().containsKey(key))
81+
.toList();
82+
for (String attributeName : attributeParams) {
8183
Attribute attribute = featureType.getAttributeFromName(attributeName);
8284
if (attribute == null) {
8385
throw new IllegalArgumentException(attributeName + " is not a valid attribute under feature type " + featureType.getName());

modules/autotagging-commons/src/test/java/org/opensearch/rule/rest/RestGetRuleActionTests.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,26 @@
88

99
package org.opensearch.rule.rest;
1010

11+
import org.opensearch.rest.RestRequest;
12+
import org.opensearch.rest.RestRequest.Method;
13+
import org.opensearch.rule.InMemoryRuleProcessingServiceTests;
14+
import org.opensearch.rule.autotagging.FeatureType;
1115
import org.opensearch.test.OpenSearchTestCase;
16+
import org.opensearch.test.rest.FakeRestRequest;
17+
import org.junit.Before;
18+
19+
import java.util.Map;
20+
21+
import static org.opensearch.rule.rest.RestGetRuleAction.FEATURE_TYPE;
1222

1323
public class RestGetRuleActionTests extends OpenSearchTestCase {
14-
RestGetRuleAction action = new RestGetRuleAction();;
24+
25+
private RestGetRuleAction action;
26+
27+
@Before
28+
public void setUpAction() {
29+
action = new RestGetRuleAction();
30+
}
1531

1632
public void testGetName() {
1733
assertEquals("get_rule", action.getName());
@@ -23,4 +39,12 @@ public void testRoutes() {
2339
assertTrue(routes.stream().anyMatch(r -> r.getPath().equals("_rules/{featureType}/")));
2440
assertTrue(routes.stream().anyMatch(r -> r.getPath().equals("_rules/{featureType}/{id}")));
2541
}
42+
43+
public void testPrepareRequestFiltersAllowedAttributes() {
44+
FeatureType featureType = InMemoryRuleProcessingServiceTests.WLMFeatureType.WLM;
45+
String validAttrName = featureType.getAllowedAttributesRegistry().keySet().iterator().next();
46+
Map<String, String> params = Map.of(FEATURE_TYPE, featureType.getName(), validAttrName, "value1", "invalidAttr", "shouldBeIgnored");
47+
RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withMethod(Method.GET).withParams(params).build();
48+
assertNotNull(action.prepareRequest(request, null));
49+
}
2650
}

plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanism.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.opensearch.common.settings.Settings;
1616
import org.opensearch.common.unit.TimeValue;
1717
import org.opensearch.core.action.ActionListener;
18+
import org.opensearch.index.IndexNotFoundException;
1819
import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider;
1920
import org.opensearch.plugin.wlm.rule.sync.detect.RuleEvent;
2021
import org.opensearch.plugin.wlm.rule.sync.detect.RuleEventClassifier;
@@ -121,6 +122,10 @@ public void onResponse(GetRuleResponse response) {
121122

122123
@Override
123124
public void onFailure(Exception e) {
125+
if (e instanceof IndexNotFoundException) {
126+
logger.debug("Rule index not found, skipping rule processing.");
127+
return;
128+
}
124129
logger.warn("Failed to get rules from persistence service", e);
125130
}
126131
}

plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/sync/RefreshBasedSyncMechanismTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.opensearch.common.settings.ClusterSettings;
1212
import org.opensearch.common.settings.Settings;
1313
import org.opensearch.core.action.ActionListener;
14+
import org.opensearch.index.IndexNotFoundException;
1415
import org.opensearch.plugin.wlm.AutoTaggingActionFilterTests;
1516
import org.opensearch.plugin.wlm.WlmClusterSettingValuesProvider;
1617
import org.opensearch.plugin.wlm.WorkloadManagementPlugin;
@@ -247,4 +248,17 @@ public void test_doRun_RefreshesRulesAndCheckInMemoryView() {
247248
// Here 1 is due to add in the second run and 10 for adding 10 rules as part of first run
248249
verify(ruleProcessingService, times(updateEventCount + 1 + 10)).add(any(Rule.class));
249250
}
251+
252+
@SuppressWarnings("unchecked")
253+
public void testDoRunIgnoresIndexNotFoundException() {
254+
doAnswer(invocation -> {
255+
ActionListener<GetRuleResponse> listener = invocation.getArgument(1);
256+
listener.onFailure(new IndexNotFoundException("rules index not found"));
257+
return null;
258+
}).when(rulePersistenceService).getRule(any(GetRuleRequest.class), any(ActionListener.class));
259+
sut.doRun();
260+
verify(rulePersistenceService, times(1)).getRule(any(GetRuleRequest.class), any(ActionListener.class));
261+
verify(ruleProcessingService, times(0)).add(any(Rule.class));
262+
verify(ruleProcessingService, times(0)).remove(any(Rule.class));
263+
}
250264
}

0 commit comments

Comments
 (0)