diff --git a/.idea/runConfigurations/Debug_OpenSearch.xml b/.idea/runConfigurations/Debug_OpenSearch.xml
index 0d8bf59823acf..c18046f873477 100644
--- a/.idea/runConfigurations/Debug_OpenSearch.xml
+++ b/.idea/runConfigurations/Debug_OpenSearch.xml
@@ -6,6 +6,10 @@
+
+
+
+
-
+
\ No newline at end of file
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java
index c86490552f2f2..5d26bd1993dac 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPlugin.java
@@ -18,21 +18,27 @@
import org.opensearch.common.settings.Settings;
import org.opensearch.common.settings.SettingsFilter;
import org.opensearch.core.action.ActionResponse;
-import org.opensearch.plugin.wlm.action.CreateQueryGroupAction;
-import org.opensearch.plugin.wlm.action.DeleteQueryGroupAction;
-import org.opensearch.plugin.wlm.action.GetQueryGroupAction;
-import org.opensearch.plugin.wlm.action.TransportCreateQueryGroupAction;
-import org.opensearch.plugin.wlm.action.TransportDeleteQueryGroupAction;
-import org.opensearch.plugin.wlm.action.TransportGetQueryGroupAction;
-import org.opensearch.plugin.wlm.action.TransportUpdateQueryGroupAction;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupAction;
-import org.opensearch.plugin.wlm.rest.RestCreateQueryGroupAction;
-import org.opensearch.plugin.wlm.rest.RestDeleteQueryGroupAction;
-import org.opensearch.plugin.wlm.rest.RestGetQueryGroupAction;
-import org.opensearch.plugin.wlm.rest.RestUpdateQueryGroupAction;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.indices.SystemIndexDescriptor;
+import org.opensearch.plugin.wlm.querygroup.action.CreateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.DeleteQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.GetQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.TransportCreateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.TransportDeleteQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.TransportGetQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.TransportUpdateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.rest.RestCreateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.rest.RestDeleteQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.rest.RestGetQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.rest.RestUpdateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.rule.action.*;
+import org.opensearch.plugin.wlm.rule.rest.RestCreateRuleAction;
+import org.opensearch.plugin.wlm.rule.rest.RestDeleteRuleAction;
+import org.opensearch.plugin.wlm.rule.rest.RestGetRuleAction;
import org.opensearch.plugins.ActionPlugin;
import org.opensearch.plugins.Plugin;
+import org.opensearch.plugins.SystemIndexPlugin;
import org.opensearch.rest.RestController;
import org.opensearch.rest.RestHandler;
@@ -40,10 +46,12 @@
import java.util.List;
import java.util.function.Supplier;
+import static org.opensearch.plugin.wlm.rule.service.RulePersistenceService.RULE_INDEX;
+
/**
* Plugin class for WorkloadManagement
*/
-public class WorkloadManagementPlugin extends Plugin implements ActionPlugin {
+public class WorkloadManagementPlugin extends Plugin implements ActionPlugin, SystemIndexPlugin {
/**
* Default constructor
@@ -56,8 +64,19 @@ public WorkloadManagementPlugin() {}
new ActionPlugin.ActionHandler<>(CreateQueryGroupAction.INSTANCE, TransportCreateQueryGroupAction.class),
new ActionPlugin.ActionHandler<>(GetQueryGroupAction.INSTANCE, TransportGetQueryGroupAction.class),
new ActionPlugin.ActionHandler<>(DeleteQueryGroupAction.INSTANCE, TransportDeleteQueryGroupAction.class),
- new ActionPlugin.ActionHandler<>(UpdateQueryGroupAction.INSTANCE, TransportUpdateQueryGroupAction.class)
+ new ActionPlugin.ActionHandler<>(UpdateQueryGroupAction.INSTANCE, TransportUpdateQueryGroupAction.class),
+ new ActionPlugin.ActionHandler<>(CreateRuleAction.INSTANCE, TransportCreateRuleAction.class),
+ new ActionPlugin.ActionHandler<>(GetRuleAction.INSTANCE, TransportGetRuleAction.class),
+ new ActionPlugin.ActionHandler<>(DeleteRuleAction.INSTANCE, TransportDeleteRuleAction.class)
+ );
+ }
+
+ @Override
+ public Collection getSystemIndexDescriptors(Settings settings) {
+ List descriptors = List.of(
+ new SystemIndexDescriptor(RULE_INDEX, "System index used for storing rules")
);
+ return descriptors;
}
@Override
@@ -74,7 +93,10 @@ public List getRestHandlers(
new RestCreateQueryGroupAction(),
new RestGetQueryGroupAction(),
new RestDeleteQueryGroupAction(),
- new RestUpdateQueryGroupAction()
+ new RestUpdateQueryGroupAction(),
+ new RestCreateRuleAction(),
+ new RestGetRuleAction(),
+ new RestDeleteRuleAction()
);
}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java
index b7c7805639eb2..9f1e0d5f5dab0 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/WorkloadManagementPluginModule.java
@@ -10,7 +10,7 @@
import org.opensearch.common.inject.AbstractModule;
import org.opensearch.common.inject.Singleton;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
/**
* Guice Module to manage WorkloadManagement related objects
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupAction.java
similarity index 94%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupAction.java
index 14cb8cfcd125a..3ca7ba97366d1 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionType;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupRequest.java
similarity index 97%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupRequest.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupRequest.java
index 1ce04faa7ccc1..b122057da9485 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupRequest.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupRequest.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.action.support.clustermanager.ClusterManagerNodeRequest;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupResponse.java
similarity index 97%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupResponse.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupResponse.java
index 9a2a8178c0a29..8616208eb2d9c 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/CreateQueryGroupResponse.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupResponse.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.cluster.metadata.QueryGroup;
import org.opensearch.core.action.ActionResponse;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupAction.java
similarity index 94%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupAction.java
index b638dbd61ca1a..7abc2ef85aaeb 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionType;
import org.opensearch.action.support.clustermanager.AcknowledgedResponse;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupRequest.java
similarity index 97%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupRequest.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupRequest.java
index e798c8e137062..2d9b095113132 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupRequest.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupRequest.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.action.support.clustermanager.AcknowledgedRequest;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupAction.java
similarity index 93%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupAction.java
index 0200185580f7d..e1ce81b3c1ed0 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionType;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupRequest.java
similarity index 96%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupRequest.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupRequest.java
index 0524c615a84e7..2c9ceab5bf1dc 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupRequest.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupRequest.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.action.support.clustermanager.ClusterManagerNodeReadRequest;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupResponse.java
similarity index 97%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupResponse.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupResponse.java
index 547c501e6a28e..625cb423cd3f9 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/GetQueryGroupResponse.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupResponse.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.cluster.metadata.QueryGroup;
import org.opensearch.core.action.ActionResponse;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportCreateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportCreateQueryGroupAction.java
similarity index 95%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportCreateQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportCreateQueryGroupAction.java
index dff9c429d63b0..e6f3216d1045c 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportCreateQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportCreateQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.clustermanager.TransportClusterManagerNodeAction;
@@ -17,7 +17,7 @@
import org.opensearch.common.inject.Inject;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.common.io.stream.StreamInput;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportDeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportDeleteQueryGroupAction.java
similarity index 95%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportDeleteQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportDeleteQueryGroupAction.java
index dd37f9df399ce..fd99f016af0d4 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportDeleteQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportDeleteQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.clustermanager.AcknowledgedResponse;
@@ -19,7 +19,7 @@
import org.opensearch.common.inject.Inject;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.common.io.stream.StreamInput;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportGetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportGetQueryGroupAction.java
similarity index 96%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportGetQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportGetQueryGroupAction.java
index 51bb21b255511..64f92e2ef1129 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportGetQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportGetQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -23,7 +23,7 @@
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.rest.RestStatus;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
import org.opensearch.search.pipeline.SearchPipelineService;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportUpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportUpdateQueryGroupAction.java
similarity index 95%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportUpdateQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportUpdateQueryGroupAction.java
index 09a0da7086b36..493ed6a56aeb5 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/TransportUpdateQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/TransportUpdateQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.clustermanager.TransportClusterManagerNodeAction;
@@ -17,7 +17,7 @@
import org.opensearch.common.inject.Inject;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.common.io.stream.StreamInput;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupAction.java
similarity index 94%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupAction.java
index ff472f206131c..ffc0c388b98c8 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupAction.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionType;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupRequest.java
similarity index 98%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupRequest.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupRequest.java
index 18af58289be13..4c773d5ab9dc6 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupRequest.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupRequest.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.action.support.clustermanager.ClusterManagerNodeRequest;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupResponse.java
similarity index 97%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupResponse.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupResponse.java
index 9071f52ecb5a7..694770bd63d12 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupResponse.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupResponse.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.cluster.metadata.QueryGroup;
import org.opensearch.core.action.ActionResponse;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/package-info.java
new file mode 100644
index 0000000000000..472b41716b44d
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/action/package-info.java
@@ -0,0 +1,12 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+/**
+ * Package for the action classes related to query groups in WorkloadManagementPlugin
+ */
+package org.opensearch.plugin.wlm.querygroup.action;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestCreateQueryGroupAction.java
similarity index 89%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestCreateQueryGroupAction.java
index b0e0af4f9d17f..08a9c3ca4fcf6 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestCreateQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestCreateQueryGroupAction.java
@@ -6,15 +6,15 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.rest;
+package org.opensearch.plugin.wlm.querygroup.rest;
import org.opensearch.client.node.NodeClient;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.ToXContent;
import org.opensearch.core.xcontent.XContentParser;
-import org.opensearch.plugin.wlm.action.CreateQueryGroupAction;
-import org.opensearch.plugin.wlm.action.CreateQueryGroupRequest;
-import org.opensearch.plugin.wlm.action.CreateQueryGroupResponse;
+import org.opensearch.plugin.wlm.querygroup.action.CreateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.CreateQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.CreateQueryGroupResponse;
import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.BytesRestResponse;
import org.opensearch.rest.RestChannel;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestDeleteQueryGroupAction.java
similarity index 89%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestDeleteQueryGroupAction.java
index 8ad621cf8a1e4..b6f532f79edba 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestDeleteQueryGroupAction.java
@@ -6,11 +6,11 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.rest;
+package org.opensearch.plugin.wlm.querygroup.rest;
import org.opensearch.client.node.NodeClient;
-import org.opensearch.plugin.wlm.action.DeleteQueryGroupAction;
-import org.opensearch.plugin.wlm.action.DeleteQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.DeleteQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.DeleteQueryGroupRequest;
import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.RestRequest;
import org.opensearch.rest.action.RestToXContentListener;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestGetQueryGroupAction.java
similarity index 88%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestGetQueryGroupAction.java
index c87973e113138..b5b4c0e36e56d 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestGetQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestGetQueryGroupAction.java
@@ -6,14 +6,14 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.rest;
+package org.opensearch.plugin.wlm.querygroup.rest;
import org.opensearch.client.node.NodeClient;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.ToXContent;
-import org.opensearch.plugin.wlm.action.GetQueryGroupAction;
-import org.opensearch.plugin.wlm.action.GetQueryGroupRequest;
-import org.opensearch.plugin.wlm.action.GetQueryGroupResponse;
+import org.opensearch.plugin.wlm.querygroup.action.GetQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.GetQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.GetQueryGroupResponse;
import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.BytesRestResponse;
import org.opensearch.rest.RestChannel;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestUpdateQueryGroupAction.java
similarity index 89%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestUpdateQueryGroupAction.java
index 55b4bc5a295c4..644d905d9cf53 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/RestUpdateQueryGroupAction.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/RestUpdateQueryGroupAction.java
@@ -6,15 +6,15 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.rest;
+package org.opensearch.plugin.wlm.querygroup.rest;
import org.opensearch.client.node.NodeClient;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.ToXContent;
import org.opensearch.core.xcontent.XContentParser;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupAction;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupRequest;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupResponse;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupResponse;
import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.BytesRestResponse;
import org.opensearch.rest.RestChannel;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/package-info.java
new file mode 100644
index 0000000000000..a51d67a6cb3b7
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/rest/package-info.java
@@ -0,0 +1,12 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+/**
+ * Package for the rest classes related to query groups in WorkloadManagementPlugin
+ */
+package org.opensearch.plugin.wlm.querygroup.rest;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/service/QueryGroupPersistenceService.java
similarity index 97%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/service/QueryGroupPersistenceService.java
index 73dff306d0e69..eef80e8deb1a9 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceService.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/service/QueryGroupPersistenceService.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.service;
+package org.opensearch.plugin.wlm.querygroup.service;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -27,10 +27,10 @@
import org.opensearch.common.settings.Settings;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.rest.RestStatus;
-import org.opensearch.plugin.wlm.action.CreateQueryGroupResponse;
-import org.opensearch.plugin.wlm.action.DeleteQueryGroupRequest;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupRequest;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupResponse;
+import org.opensearch.plugin.wlm.querygroup.action.CreateQueryGroupResponse;
+import org.opensearch.plugin.wlm.querygroup.action.DeleteQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupResponse;
import org.opensearch.wlm.MutableQueryGroupFragment;
import org.opensearch.wlm.ResourceType;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/service/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/service/package-info.java
new file mode 100644
index 0000000000000..3758c9fcd9b81
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/querygroup/service/package-info.java
@@ -0,0 +1,12 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+/**
+ * Package for the service classes related to query groups in WorkloadManagementPlugin
+ */
+package org.opensearch.plugin.wlm.querygroup.service;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleAction.java
new file mode 100644
index 0000000000000..14831c4f0e95a
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleAction.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.ActionType;
+
+/**
+ * Transport action to create Rule
+ *
+ * @opensearch.experimental
+ */
+public class CreateRuleAction extends ActionType {
+
+ /**
+ * An instance of CreateRuleAction
+ */
+ public static final CreateRuleAction INSTANCE = new CreateRuleAction();
+
+ /**
+ * Name for CreateRuleAction
+ */
+ public static final String NAME = "cluster:admin/opensearch/wlm/rule/_create";
+
+ /**
+ * Default constructor
+ */
+ private CreateRuleAction() {
+ super(NAME, CreateRuleResponse::new);
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleRequest.java
new file mode 100644
index 0000000000000..ee8d46f0f55ba
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleRequest.java
@@ -0,0 +1,74 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.ActionRequestValidationException;
+import org.opensearch.action.support.clustermanager.ClusterManagerNodeRequest;
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.cluster.metadata.Rule.Builder;
+import org.opensearch.common.UUIDs;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.xcontent.XContentParser;
+import org.joda.time.Instant;
+
+import java.io.IOException;
+
+/**
+ * A request for create Rule
+ * @opensearch.experimental
+ */
+public class CreateRuleRequest extends ClusterManagerNodeRequest {
+ private final Rule rule;
+
+
+ /**
+ * Constructor for CreateRuleRequest
+ * @param rule - A {@link Rule} object
+ */
+ CreateRuleRequest(Rule rule) {
+ this.rule = rule;
+ }
+
+ /**
+ * Constructor for CreateRuleRequest
+ * @param in - A {@link StreamInput} object
+ */
+ CreateRuleRequest(StreamInput in) throws IOException {
+ super(in);
+ rule = new Rule(in);
+ }
+
+ /**
+ * Generate a CreateRuleRequest from XContent
+ * @param parser - A {@link XContentParser} object
+ */
+ public static CreateRuleRequest fromXContent(XContentParser parser) throws IOException {
+ Builder builder = Builder.fromXContent(parser);
+ return new CreateRuleRequest(builder._id(UUIDs.randomBase64UUID()).updatedAt(Instant.now().toString()).build());
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ return null;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ rule.writeTo(out);
+ }
+
+ /**
+ * Rule getter
+ */
+ public Rule getRule() {
+ return rule;
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleResponse.java
new file mode 100644
index 0000000000000..d312c383f3ca9
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/CreateRuleResponse.java
@@ -0,0 +1,75 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.cluster.metadata.QueryGroup;
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.core.action.ActionResponse;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.ToXContentObject;
+import org.opensearch.core.xcontent.XContentBuilder;
+
+import java.io.IOException;
+
+/**
+ * Response for the create API for Rule
+ *
+ * @opensearch.experimental
+ */
+public class CreateRuleResponse extends ActionResponse implements ToXContent, ToXContentObject {
+ private final Rule rule;
+ private final RestStatus restStatus;
+
+ /**
+ * Constructor for CreateRuleResponse
+ * @param rule - The Rule to be included in the response
+ * @param restStatus - The restStatus for the response
+ */
+ public CreateRuleResponse(final Rule rule, RestStatus restStatus) {
+ this.rule = rule;
+ this.restStatus = restStatus;
+ }
+
+ /**
+ * Constructor for CreateRuleResponse
+ * @param in - A {@link StreamInput} object
+ */
+ public CreateRuleResponse(StreamInput in) throws IOException {
+ rule = new Rule(in);
+ restStatus = RestStatus.readFrom(in);
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ rule.writeTo(out);
+ RestStatus.writeTo(out, restStatus);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ return rule.toXContent(builder, params);
+ }
+
+ /**
+ * rule getter
+ */
+ public Rule getRule() {
+ return rule;
+ }
+
+ /**
+ * restStatus getter
+ */
+ public RestStatus getRestStatus() {
+ return restStatus;
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleAction.java
new file mode 100644
index 0000000000000..2814686c39a2c
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleAction.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.ActionType;
+
+/**
+ * Transport action to delete a Rule
+ *
+ * @opensearch.experimental
+ */
+public class DeleteRuleAction extends ActionType {
+
+ /**
+ * An instance of DeleteRuleAction
+ */
+ public static final DeleteRuleAction INSTANCE = new DeleteRuleAction();
+
+ /**
+ * Name for DeleteRuleAction
+ */
+ public static final String NAME = "cluster:admin/opensearch/wlm/rule/delete";
+
+ /**
+ * Default constructor
+ */
+ private DeleteRuleAction() {
+ super(NAME, DeleteRuleResponse::new);
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleRequest.java
new file mode 100644
index 0000000000000..4bc389ab84d53
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleRequest.java
@@ -0,0 +1,60 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.ActionRequestValidationException;
+import org.opensearch.action.support.clustermanager.ClusterManagerNodeRequest;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+
+import java.io.IOException;
+
+/**
+ * A request for deleting a Rule
+ * @opensearch.experimental
+ */
+public class DeleteRuleRequest extends ClusterManagerNodeRequest {
+ private final String _id;
+
+ /**
+ * Constructor for DeleteRuleRequest
+ * @param _id - Rule _id that we want to delete
+ */
+ public DeleteRuleRequest(String _id) {
+ this._id = _id;
+ }
+
+ /**
+ * Constructor for DeleteRuleRequest
+ * @param in - A {@link StreamInput} object
+ */
+ public DeleteRuleRequest(StreamInput in) throws IOException {
+ super(in);
+ _id = in.readOptionalString();
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ return null;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ out.writeOptionalString(_id);
+ }
+
+ /**
+ * _id getter
+ */
+ public String get_id() {
+ return _id;
+ }
+}
+
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleResponse.java
new file mode 100644
index 0000000000000..0da11faf008d8
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/DeleteRuleResponse.java
@@ -0,0 +1,63 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.core.action.ActionResponse;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.ToXContentObject;
+import org.opensearch.core.xcontent.XContentBuilder;
+
+import java.io.IOException;
+
+/**
+ * Response for the delete API for Rule
+ *
+ * @opensearch.experimental
+ */
+public class DeleteRuleResponse extends ActionResponse implements ToXContent, ToXContentObject {
+ private final boolean acknowledged;
+
+ /**
+ * Constructor for DeleteRuleResponse
+ * @param acknowledged - Whether the deletion was successful
+ */
+ public DeleteRuleResponse(boolean acknowledged) {
+ this.acknowledged = acknowledged;
+ }
+
+ /**
+ * Constructor for DeleteRuleResponse
+ * @param in - A {@link StreamInput} object
+ */
+ public DeleteRuleResponse(StreamInput in) throws IOException {
+ this.acknowledged = in.readBoolean();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeBoolean(acknowledged);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+ builder.field("acknowledged", acknowledged);
+ builder.endObject();
+ return builder;
+ }
+
+ /**
+ * acknowledged getter
+ */
+ public boolean isAcknowledged() {
+ return acknowledged;
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleAction.java
new file mode 100644
index 0000000000000..0764ce100f1d1
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleAction.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.ActionType;
+
+/**
+ * Transport action to get Rule
+ *
+ * @opensearch.experimental
+ */
+public class GetRuleAction extends ActionType {
+
+ /**
+ * An instance of GetRuleAction
+ */
+ public static final GetRuleAction INSTANCE = new GetRuleAction();
+
+ /**
+ * Name for GetRuleAction
+ */
+ public static final String NAME = "cluster:admin/opensearch/wlm/rule/_get";
+
+ /**
+ * Default constructor
+ */
+ private GetRuleAction() {
+ super(NAME, GetRuleResponse::new);
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleRequest.java
new file mode 100644
index 0000000000000..c271984ad28a5
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleRequest.java
@@ -0,0 +1,64 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.joda.time.Instant;
+import org.opensearch.action.ActionRequestValidationException;
+import org.opensearch.action.support.clustermanager.ClusterManagerNodeRequest;
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.cluster.metadata.Rule.Builder;
+import org.opensearch.common.UUIDs;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.xcontent.XContentParser;
+
+import java.io.IOException;
+
+/**
+ * A request for get Rule
+ * @opensearch.experimental
+ */
+public class GetRuleRequest extends ClusterManagerNodeRequest {
+ private final String _id;
+
+ /**
+ * Constructor for GetRuleRequest
+ * @param _id - Rule _id that we want to get
+ */
+ public GetRuleRequest(String _id) {
+ this._id = _id;
+ }
+
+ /**
+ * Constructor for GetRuleRequest
+ * @param in - A {@link StreamInput} object
+ */
+ public GetRuleRequest(StreamInput in) throws IOException {
+ super(in);
+ _id = in.readOptionalString();
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ return null;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ out.writeOptionalString(_id);
+ }
+
+ /**
+ * _id getter
+ */
+ public String get_id() {
+ return _id;
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleResponse.java
new file mode 100644
index 0000000000000..7ff65fa33e189
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/GetRuleResponse.java
@@ -0,0 +1,83 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.cluster.metadata.QueryGroup;
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.core.action.ActionResponse;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.ToXContentObject;
+import org.opensearch.core.xcontent.XContentBuilder;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Response for the get API for Rule
+ *
+ * @opensearch.experimental
+ */
+public class GetRuleResponse extends ActionResponse implements ToXContent, ToXContentObject {
+ private final List rules;
+ private final RestStatus restStatus;
+
+ /**
+ * Constructor for GetRuleResponse
+ * @param rules - The List of Rules to be included in the response
+ * @param restStatus - The restStatus for the response
+ */
+ public GetRuleResponse(final List rules, RestStatus restStatus) {
+ this.rules = rules;
+ this.restStatus = restStatus;
+ }
+
+ /**
+ * Constructor for GetRuleResponse
+ * @param in - A {@link StreamInput} object
+ */
+ public GetRuleResponse(StreamInput in) throws IOException {
+ this.rules = in.readList(Rule::new);
+ restStatus = RestStatus.readFrom(in);
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeCollection(rules);
+ RestStatus.writeTo(out, restStatus);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+ builder.startArray("rules");
+ for (Rule rule : rules) {
+ rule.toXContent(builder, params);
+ }
+ builder.endArray();
+ builder.endObject();
+ return builder;
+ }
+
+ /**
+ * rules getter
+ */
+ public List getRules() {
+ return rules;
+ }
+
+ /**
+ * restStatus getter
+ */
+ public RestStatus getRestStatus() {
+ return restStatus;
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportCreateRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportCreateRuleAction.java
new file mode 100644
index 0000000000000..0d539f5ef293e
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportCreateRuleAction.java
@@ -0,0 +1,65 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.admin.cluster.remote.RemoteInfoAction;
+import org.opensearch.action.admin.cluster.remote.RemoteInfoRequest;
+import org.opensearch.action.admin.cluster.remote.RemoteInfoResponse;
+import org.opensearch.action.support.ActionFilters;
+import org.opensearch.action.support.HandledTransportAction;
+import org.opensearch.action.support.TransportAction;
+import org.opensearch.action.support.clustermanager.TransportClusterManagerNodeAction;
+import org.opensearch.cluster.ClusterState;
+import org.opensearch.cluster.block.ClusterBlockException;
+import org.opensearch.cluster.block.ClusterBlockLevel;
+import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
+import org.opensearch.common.inject.Inject;
+import org.opensearch.core.action.ActionListener;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.plugin.wlm.rule.service.RulePersistenceService;
+import org.opensearch.tasks.Task;
+import org.opensearch.threadpool.ThreadPool;
+import org.opensearch.transport.TransportService;
+
+import java.io.IOException;
+
+import static java.util.stream.Collectors.toList;
+import static org.opensearch.threadpool.ThreadPool.Names.SAME;
+
+/**
+ * Transport action to create Rule
+ *
+ * @opensearch.experimental
+ */
+public class TransportCreateRuleAction extends HandledTransportAction {
+
+ private final RulePersistenceService rulePersistenceService;
+
+ /**
+ * Constructor for TransportCreateRuleAction
+ *
+ * @param transportService - a {@link TransportService} object
+ * @param actionFilters - a {@link ActionFilters} object
+ * @param rulePersistenceService - a {@link RulePersistenceService} object
+ */
+ @Inject
+ public TransportCreateRuleAction(
+ TransportService transportService,
+ ActionFilters actionFilters,
+ RulePersistenceService rulePersistenceService
+ ) {
+ super(CreateRuleAction.NAME, transportService, actionFilters, CreateRuleRequest::new);
+ this.rulePersistenceService = rulePersistenceService;
+ }
+
+ @Override
+ protected void doExecute(Task task, CreateRuleRequest request, ActionListener listener) {
+ rulePersistenceService.createRule(request.getRule(), listener);
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportDeleteRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportDeleteRuleAction.java
new file mode 100644
index 0000000000000..1f3cc870a64e2
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportDeleteRuleAction.java
@@ -0,0 +1,58 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.support.ActionFilters;
+import org.opensearch.action.support.HandledTransportAction;
+import org.opensearch.common.inject.Inject;
+import org.opensearch.core.action.ActionListener;
+import org.opensearch.plugin.wlm.rule.service.RulePersistenceService;
+import org.opensearch.tasks.Task;
+import org.opensearch.transport.TransportService;
+
+/**
+ * Transport action to delete a Rule
+ *
+ * @opensearch.experimental
+ */
+/**
+ * Transport action to delete a Rule
+ *
+ * @opensearch.experimental
+ */
+public class TransportDeleteRuleAction extends HandledTransportAction {
+
+ private final RulePersistenceService rulePersistenceService;
+
+ /**
+ * Constructor for TransportDeleteRuleAction
+ *
+ * @param transportService - a {@link TransportService} object
+ * @param actionFilters - a {@link ActionFilters} object
+ * @param rulePersistenceService - a {@link RulePersistenceService} object
+ */
+ @Inject
+ public TransportDeleteRuleAction(
+ TransportService transportService,
+ ActionFilters actionFilters,
+ RulePersistenceService rulePersistenceService
+ ) {
+ super(DeleteRuleAction.NAME, transportService, actionFilters, DeleteRuleRequest::new);
+ this.rulePersistenceService = rulePersistenceService;
+ }
+
+ @Override
+ protected void doExecute(Task task, DeleteRuleRequest request, ActionListener listener) {
+ rulePersistenceService.deleteRule(request.get_id(), ActionListener.wrap(
+ response -> listener.onResponse(new DeleteRuleResponse(true)),
+ listener::onFailure
+ ));
+ }
+}
+
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportGetRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportGetRuleAction.java
new file mode 100644
index 0000000000000..bbc0dff952f26
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportGetRuleAction.java
@@ -0,0 +1,49 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.support.ActionFilters;
+import org.opensearch.action.support.HandledTransportAction;
+import org.opensearch.common.inject.Inject;
+import org.opensearch.core.action.ActionListener;
+import org.opensearch.plugin.wlm.rule.service.RulePersistenceService;
+import org.opensearch.tasks.Task;
+import org.opensearch.transport.TransportService;
+
+/**
+ * Transport action to get Rule
+ *
+ * @opensearch.experimental
+ */
+public class TransportGetRuleAction extends HandledTransportAction {
+
+ private final RulePersistenceService rulePersistenceService;
+
+ /**
+ * Constructor for TransportGetRuleAction
+ *
+ * @param transportService - a {@link TransportService} object
+ * @param actionFilters - a {@link ActionFilters} object
+ * @param rulePersistenceService - a {@link RulePersistenceService} object
+ */
+ @Inject
+ public TransportGetRuleAction(
+ TransportService transportService,
+ ActionFilters actionFilters,
+ RulePersistenceService rulePersistenceService
+ ) {
+ super(GetRuleAction.NAME, transportService, actionFilters, GetRuleRequest::new);
+ this.rulePersistenceService = rulePersistenceService;
+ }
+
+ @Override
+ protected void doExecute(Task task, GetRuleRequest request, ActionListener listener) {
+ rulePersistenceService.getRule(request.get_id(), listener);
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportUpdateRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportUpdateRuleAction.java
new file mode 100644
index 0000000000000..48c373fcce3e2
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/TransportUpdateRuleAction.java
@@ -0,0 +1,49 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.support.ActionFilters;
+import org.opensearch.action.support.HandledTransportAction;
+import org.opensearch.common.inject.Inject;
+import org.opensearch.core.action.ActionListener;
+import org.opensearch.plugin.wlm.rule.service.RulePersistenceService;
+import org.opensearch.tasks.Task;
+import org.opensearch.transport.TransportService;
+
+/**
+ * Transport action to update Rule
+ *
+ * @opensearch.experimental
+ */
+public class TransportUpdateRuleAction extends HandledTransportAction {
+
+ private final RulePersistenceService rulePersistenceService;
+
+ /**
+ * Constructor for TransportUpdateRuleAction
+ *
+ * @param transportService - a {@link TransportService} object
+ * @param actionFilters - a {@link ActionFilters} object
+ * @param rulePersistenceService - a {@link RulePersistenceService} object
+ */
+ @Inject
+ public TransportUpdateRuleAction(
+ TransportService transportService,
+ ActionFilters actionFilters,
+ RulePersistenceService rulePersistenceService
+ ) {
+ super(UpdateRuleAction.NAME, transportService, actionFilters, UpdateRuleRequest::new);
+ this.rulePersistenceService = rulePersistenceService;
+ }
+
+ @Override
+ protected void doExecute(Task task, UpdateRuleRequest request, ActionListener listener) {
+
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleAction.java
new file mode 100644
index 0000000000000..c9616e77a4e3c
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleAction.java
@@ -0,0 +1,36 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.action.ActionType;
+
+/**
+ * Transport action to update Rule
+ *
+ * @opensearch.experimental
+ */
+public class UpdateRuleAction extends ActionType {
+
+ /**
+ * An instance of UpdateRuleAction
+ */
+ public static final UpdateRuleAction INSTANCE = new UpdateRuleAction();
+
+ /**
+ * Name for UpdateRuleAction
+ */
+ public static final String NAME = "cluster:admin/opensearch/wlm/rule/_update";
+
+ /**
+ * Default constructor
+ */
+ private UpdateRuleAction() {
+ super(NAME, UpdateRuleResponse::new);
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleRequest.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleRequest.java
new file mode 100644
index 0000000000000..68ddd92111817
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleRequest.java
@@ -0,0 +1,83 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.joda.time.Instant;
+import org.opensearch.action.ActionRequestValidationException;
+import org.opensearch.action.support.clustermanager.ClusterManagerNodeRequest;
+import org.opensearch.cluster.metadata.QueryGroup;
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.cluster.metadata.Rule.Builder;
+import org.opensearch.common.UUIDs;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.xcontent.XContentParser;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupRequest;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A request for update Rule
+ * @opensearch.experimental
+ */
+public class UpdateRuleRequest extends ClusterManagerNodeRequest {
+// private final String _id;
+// private final Map> attributeMap;
+// private final String label;
+ private Rule rule;
+
+ /**
+ * Constructor for UpdateRuleRequest
+ * @param rule - A {@link Rule} object
+ */
+ UpdateRuleRequest(Rule rule) {
+ this.rule = rule;
+ }
+
+ /**
+ * Constructor for UpdateRuleRequest
+ * @param in - A {@link StreamInput} object
+ */
+ UpdateRuleRequest(StreamInput in) throws IOException {
+ super(in);
+ rule = new Rule(in);
+ }
+
+ /**
+ * Generate a UpdateRuleRequest from XContent
+ * @param parser - A {@link XContentParser} object
+ */
+ public static UpdateRuleRequest fromXContent(XContentParser parser, String _id) throws IOException {
+ Builder builder = Builder.fromXContent(parser);
+ if (builder.getLabel() == null) {
+ builder.label(""); //TODO: check
+ }
+ return new UpdateRuleRequest(builder._id(_id).updatedAt(Instant.now().toString()).build());
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ return null;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ rule.writeTo(out);
+ }
+
+ /**
+ * Rule getter
+ */
+ public Rule getRule() {
+ return rule;
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleResponse.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleResponse.java
new file mode 100644
index 0000000000000..14c305b088183
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/UpdateRuleResponse.java
@@ -0,0 +1,74 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.core.action.ActionResponse;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.ToXContentObject;
+import org.opensearch.core.xcontent.XContentBuilder;
+
+import java.io.IOException;
+
+/**
+ * Response for the update API for Rule
+ *
+ * @opensearch.experimental
+ */
+public class UpdateRuleResponse extends ActionResponse implements ToXContent, ToXContentObject {
+ private final Rule rule;
+ private final RestStatus restStatus;
+
+ /**
+ * Constructor for UpdateRuleResponse
+ * @param rule - The Rule to be included in the response
+ * @param restStatus - The restStatus for the response
+ */
+ public UpdateRuleResponse(final Rule rule, RestStatus restStatus) {
+ this.rule = rule;
+ this.restStatus = restStatus;
+ }
+
+ /**
+ * Constructor for UpdateRuleResponse
+ * @param in - A {@link StreamInput} object
+ */
+ public UpdateRuleResponse(StreamInput in) throws IOException {
+ rule = new Rule(in);
+ restStatus = RestStatus.readFrom(in);
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ rule.writeTo(out);
+ RestStatus.writeTo(out, restStatus);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ return rule.toXContent(builder, params);
+ }
+
+ /**
+ * rule getter
+ */
+ public Rule getRule() {
+ return rule;
+ }
+
+ /**
+ * restStatus getter
+ */
+ public RestStatus getRestStatus() {
+ return restStatus;
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/package-info.java
similarity index 62%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/package-info.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/package-info.java
index 7d7cb9028fdb8..b9fb278dae5b0 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rest/package-info.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/action/package-info.java
@@ -7,6 +7,6 @@
*/
/**
- * Package for the rest classes of WorkloadManagementPlugin
+ * Package for the action classes related to rules in WorkloadManagementPlugin
*/
-package org.opensearch.plugin.wlm.rest;
+package org.opensearch.plugin.wlm.rule.action;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestCreateRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestCreateRuleAction.java
new file mode 100644
index 0000000000000..c0dce030e2502
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestCreateRuleAction.java
@@ -0,0 +1,72 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.rest;
+
+import org.opensearch.client.node.NodeClient;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.XContentParser;
+import org.opensearch.plugin.wlm.rule.action.CreateRuleAction;
+import org.opensearch.plugin.wlm.rule.action.CreateRuleRequest;
+import org.opensearch.plugin.wlm.rule.action.CreateRuleResponse;
+import org.opensearch.rest.BaseRestHandler;
+import org.opensearch.rest.BytesRestResponse;
+import org.opensearch.rest.RestChannel;
+import org.opensearch.rest.RestRequest;
+import org.opensearch.rest.RestResponse;
+import org.opensearch.rest.action.RestResponseListener;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.opensearch.rest.RestRequest.Method.POST;
+import static org.opensearch.rest.RestRequest.Method.PUT;
+
+/**
+ * Rest action to create a Rule
+ *
+ * @opensearch.experimental
+ */
+public class RestCreateRuleAction extends BaseRestHandler {
+
+ /**
+ * Constructor for RestCreateRuleAction
+ */
+ public RestCreateRuleAction() {}
+
+ @Override
+ public String getName() {
+ return "create_rule";
+ }
+
+ /**
+ * The list of {@link Route}s that this RestHandler is responsible for handling.
+ */
+ @Override
+ public List routes() {
+ return List.of(new Route(POST, "_wlm/rule/"), new Route(PUT, "_wlm/rule/"));
+ }
+
+ @Override
+ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
+ try (XContentParser parser = request.contentParser()) {
+ CreateRuleRequest createRuleRequest = CreateRuleRequest.fromXContent(parser);
+ return channel -> client.execute(CreateRuleAction.INSTANCE, createRuleRequest, createRuleResponse(channel));
+ }
+ }
+
+ private RestResponseListener createRuleResponse(final RestChannel channel) {
+ return new RestResponseListener<>(channel) {
+ @Override
+ public RestResponse buildResponse(final CreateRuleResponse response) throws Exception {
+ return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS));
+ }
+ };
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestDeleteRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestDeleteRuleAction.java
new file mode 100644
index 0000000000000..4a878f00128e7
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestDeleteRuleAction.java
@@ -0,0 +1,62 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.rest;
+
+import org.opensearch.client.node.NodeClient;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.plugin.wlm.rule.action.*;
+import org.opensearch.rest.*;
+import org.opensearch.rest.action.RestResponseListener;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.opensearch.rest.RestRequest.Method.DELETE;
+
+/**
+ * Rest action to delete a Rule
+ *
+ * @opensearch.experimental
+ */
+public class RestDeleteRuleAction extends BaseRestHandler {
+
+ /**
+ * Constructor for RestDeleteRuleAction
+ */
+ public RestDeleteRuleAction() {}
+
+ @Override
+ public String getName() {
+ return "delete_rule";
+ }
+
+ /**
+ * The list of {@link Route}s that this RestHandler is responsible for handling.
+ */
+ @Override
+ public List routes() {
+ return List.of(new Route(DELETE, "_wlm/rule/{_id}"));
+ }
+
+ @Override
+ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
+ final DeleteRuleRequest deleteRuleRequest = new DeleteRuleRequest(request.param("_id"));
+ return channel -> client.execute(DeleteRuleAction.INSTANCE, deleteRuleRequest, deleteRuleResponse(channel));
+ }
+
+ private RestResponseListener deleteRuleResponse(final RestChannel channel) {
+ return new RestResponseListener<>(channel) {
+ @Override
+ public RestResponse buildResponse(final DeleteRuleResponse response) throws Exception {
+ return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS));
+ }
+ };
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestGetRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestGetRuleAction.java
new file mode 100644
index 0000000000000..935d885cd65ae
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestGetRuleAction.java
@@ -0,0 +1,65 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.rest;
+
+import org.opensearch.client.node.NodeClient;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.XContentParser;
+import org.opensearch.plugin.wlm.querygroup.action.GetQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.GetQueryGroupRequest;
+import org.opensearch.plugin.wlm.rule.action.*;
+import org.opensearch.rest.*;
+import org.opensearch.rest.action.RestResponseListener;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.opensearch.rest.RestRequest.Method.*;
+
+/**
+ * Rest action to get a Rule
+ *
+ * @opensearch.experimental
+ */
+public class RestGetRuleAction extends BaseRestHandler {
+
+ /**
+ * Constructor for RestGetRuleAction
+ */
+ public RestGetRuleAction() {}
+
+ @Override
+ public String getName() {
+ return "get_rule";
+ }
+
+ /**
+ * The list of {@link Route}s that this RestHandler is responsible for handling.
+ */
+ @Override
+ public List routes() {
+ return List.of(new Route(GET, "_wlm/rule/"), new Route(GET, "_wlm/rule/{_id}"));
+ }
+
+ @Override
+ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
+ final GetRuleRequest getRuleRequest = new GetRuleRequest(request.param("_id"));
+ return channel -> client.execute(GetRuleAction.INSTANCE, getRuleRequest, getRuleResponse(channel));
+ }
+
+ private RestResponseListener getRuleResponse(final RestChannel channel) {
+ return new RestResponseListener<>(channel) {
+ @Override
+ public RestResponse buildResponse(final GetRuleResponse response) throws Exception {
+ return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS));
+ }
+ };
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestUpdateRuleAction.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestUpdateRuleAction.java
new file mode 100644
index 0000000000000..214e396ec3adc
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/RestUpdateRuleAction.java
@@ -0,0 +1,66 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.rest;
+
+import org.opensearch.client.node.NodeClient;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.XContentParser;
+import org.opensearch.plugin.wlm.rule.action.*;
+import org.opensearch.rest.*;
+import org.opensearch.rest.action.RestResponseListener;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.opensearch.rest.RestRequest.Method.POST;
+import static org.opensearch.rest.RestRequest.Method.PUT;
+
+/**
+ * Rest action to update a Rule
+ *
+ * @opensearch.experimental
+ */
+public class RestUpdateRuleAction extends BaseRestHandler {
+
+ /**
+ * Constructor for RestUpdateRuleAction
+ */
+ public RestUpdateRuleAction() {}
+
+ @Override
+ public String getName() {
+ return "update_rule";
+ }
+
+ /**
+ * The list of {@link Route}s that this RestHandler is responsible for handling.
+ */
+ @Override
+ public List routes() {
+ return List.of(new Route(POST, "_wlm/rule/{_id}"), new Route(PUT, "_wlm/rule/{_id}"));
+ }
+
+ @Override
+ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
+ try (XContentParser parser = request.contentParser()) {
+ UpdateRuleRequest updateRuleRequest = UpdateRuleRequest.fromXContent(parser, request.param("_id"));
+ return channel -> client.execute(UpdateRuleAction.INSTANCE, updateRuleRequest, updateRuleResponse(channel));
+ }
+ }
+
+ private RestResponseListener updateRuleResponse(final RestChannel channel) {
+ return new RestResponseListener<>(channel) {
+ @Override
+ public RestResponse buildResponse(final UpdateRuleResponse response) throws Exception {
+ return new BytesRestResponse(RestStatus.OK, response.toXContent(channel.newBuilder(), ToXContent.EMPTY_PARAMS));
+ }
+ };
+ }
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/package-info.java
similarity index 63%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/package-info.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/package-info.java
index 9921500df8a81..1d82e4fea71e5 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/action/package-info.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/rest/package-info.java
@@ -7,6 +7,6 @@
*/
/**
- * Package for the action classes of WorkloadManagementPlugin
+ * Package for the rest classes related to rules in WorkloadManagementPlugin
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.rule.rest;
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/service/RulePersistenceService.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/service/RulePersistenceService.java
new file mode 100644
index 0000000000000..0b24593d64735
--- /dev/null
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/service/RulePersistenceService.java
@@ -0,0 +1,172 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.service;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.opensearch.ResourceNotFoundException;
+import org.opensearch.action.delete.DeleteRequest;
+import org.opensearch.action.delete.DeleteResponse;
+import org.opensearch.action.get.GetRequest;
+import org.opensearch.action.get.GetResponse;
+import org.opensearch.action.index.IndexRequest;
+import org.opensearch.action.search.SearchResponse;
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.common.inject.Inject;
+import org.opensearch.client.Client;
+import org.opensearch.common.xcontent.XContentFactory;
+import org.opensearch.core.action.ActionListener;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.*;
+import org.opensearch.index.query.QueryBuilders;
+import org.opensearch.plugin.wlm.rule.action.CreateRuleResponse;
+import org.opensearch.plugin.wlm.rule.action.DeleteRuleResponse;
+import org.opensearch.plugin.wlm.rule.action.GetRuleResponse;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * This class defines the functions for Rule persistence
+ */
+public class RulePersistenceService {
+ public static final String RULE_INDEX = ".rule";
+ private final Client client;
+ private static final Logger logger = LogManager.getLogger(RulePersistenceService.class);
+
+ /**
+ * Constructor for RulePersistenceService
+ *
+ * @param client {@link Client} - The client to be used by RulePersistenceService
+ */
+ @Inject
+ public RulePersistenceService(
+ final Client client
+ ) {
+ this.client = client;
+ }
+
+ public void createRule(Rule rule, ActionListener listener) {
+ try {
+ IndexRequest indexRequest = new IndexRequest(RULE_INDEX)
+ .source(rule.toXContentWithoutId(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS));
+
+ client.index(indexRequest, ActionListener.wrap(
+ indexResponse -> {
+ Rule savedRule = rule.builderFromRule()._id(indexResponse.getId()).build();
+ CreateRuleResponse createRuleResponse = new CreateRuleResponse(savedRule, RestStatus.OK);
+ listener.onResponse(createRuleResponse);
+ },
+ e -> {
+ logger.warn("failed to save Rule object due to error: {}", e.getMessage());
+ listener.onFailure(e);
+ }
+ ));
+ } catch (IOException e) {
+ logger.error("Error saving rule to index: " + RULE_INDEX, e);
+ listener.onFailure(new RuntimeException("Failed to save rule to index."));
+ }
+ }
+
+ public void getRule(String id, ActionListener listener) {
+ if (id != null) {
+ fetchRuleById(id, listener);
+ } else {
+ fetchAllRules(listener);
+ }
+ }
+
+ private void fetchRuleById(String id, ActionListener listener) {
+ client.prepareGet(RULE_INDEX, id).execute(ActionListener.wrap(
+ getResponse -> handleGetOneRuleResponse(id, getResponse, listener),
+ e -> {
+ logger.error("Failed to fetch rule with ID {}: {}", id, e.getMessage());
+ listener.onFailure(e);
+ }
+ ));
+ }
+
+ private void handleGetOneRuleResponse(String id, GetResponse getResponse, ActionListener listener) {
+ if (getResponse.isExists()) {
+ try {
+ XContentParser parser = MediaTypeRegistry.JSON.xContent()
+ .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, getResponse.getSourceAsString());
+ Rule rule = Rule.Builder.fromXContent(parser)._id(id).build();
+ listener.onResponse(new GetRuleResponse(List.of(rule), RestStatus.OK));
+ } catch (IOException e) {
+ logger.error("Error parsing rule with ID {}: {}", id, e.getMessage());
+ listener.onFailure(e);
+ }
+ } else {
+ listener.onFailure(new ResourceNotFoundException("Rule with ID " + id + " not found."));
+ }
+ }
+
+ private void fetchAllRules(ActionListener listener) {
+ client.prepareSearch(RULE_INDEX)
+ .setQuery(QueryBuilders.matchAllQuery())
+ .setSize(20)
+ .execute(ActionListener.wrap(
+ searchResponse -> handleGetAllRuleResponse(searchResponse, listener),
+ e -> {
+ logger.error("Failed to fetch all rules: {}", e.getMessage());
+ listener.onFailure(e);
+ }
+ ));
+ }
+
+ private void handleGetAllRuleResponse(SearchResponse searchResponse, ActionListener listener) {
+ List rules = Arrays.stream(searchResponse.getHits().getHits())
+ .map(hit -> {
+ try {
+ XContentParser parser = MediaTypeRegistry.JSON.xContent()
+ .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, hit.getSourceAsString());
+ return Rule.Builder.fromXContent(parser)._id(hit.getId()).build();
+ } catch (IOException e) {
+ logger.error("Failed to parse rule from hit: {}", e.getMessage());
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ listener.onResponse(new GetRuleResponse(rules, RestStatus.OK));
+ }
+
+ public void deleteRule(String id, ActionListener listener) {
+ if (id == null) {
+ listener.onFailure(new IllegalArgumentException("Rule ID must not be null"));
+ return;
+ }
+
+ // Check if the document exists before deleting
+ GetRequest getRequest = new GetRequest(RULE_INDEX, id);
+ client.get(getRequest, ActionListener.wrap(
+ getResponse -> {
+ if (!getResponse.isExists()) {
+ listener.onFailure(new ResourceNotFoundException("The rule with id " + id + " doesn't exist"));
+ } else {
+ // Proceed with deletion
+ DeleteRequest deleteRequest = new DeleteRequest(RULE_INDEX, id);
+ client.delete(deleteRequest, ActionListener.wrap(
+ deleteResponse -> {
+ boolean acknowledged = deleteResponse.getResult() == DeleteResponse.Result.DELETED;
+ listener.onResponse(new DeleteRuleResponse(acknowledged));
+ },
+ listener::onFailure
+ ));
+ }
+ },
+ listener::onFailure
+ ));
+ }
+
+}
diff --git a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/package-info.java b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/service/package-info.java
similarity index 62%
rename from plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/package-info.java
rename to plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/service/package-info.java
index 5848e9c936623..a10b1758d0a58 100644
--- a/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/service/package-info.java
+++ b/plugins/workload-management/src/main/java/org/opensearch/plugin/wlm/rule/service/package-info.java
@@ -7,6 +7,6 @@
*/
/**
- * Package for the service classes of WorkloadManagementPlugin
+ * Package for the service classes related to rules in WorkloadManagementPlugin
*/
-package org.opensearch.plugin.wlm.service;
+package org.opensearch.plugin.wlm.rule.service;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/QueryGroupTestUtils.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/QueryGroupTestUtils.java
index c6eb3140e943d..fcaeec4571d68 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/QueryGroupTestUtils.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/QueryGroupTestUtils.java
@@ -19,7 +19,7 @@
import org.opensearch.common.settings.ClusterSettings;
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Settings;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.wlm.MutableQueryGroupFragment;
import org.opensearch.wlm.ResourceType;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/RuleTestUtils.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/RuleTestUtils.java
new file mode 100644
index 0000000000000..7c3cba3bf1858
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/RuleTestUtils.java
@@ -0,0 +1,147 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm;
+
+import org.opensearch.cluster.metadata.Rule;
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.opensearch.cluster.metadata.Rule.builder;
+
+public class RuleTestUtils {
+ public static final String _ID_ONE = "AgfUO5Ja9yfvhdONlYi3TQ==";
+ public static final String _ID_TWO = "G5iIq84j7eK1qIAAAAIH53=1";
+ public static final String LABEL_ONE = "label_one";
+ public static final String LABEL_TWO = "label_two";
+ public static final String WLM_STRING = "wlm";
+ public static final String TIMESTAMP_ONE = "1738011537558";
+ public static final String TIMESTAMP_TWO = "1738013454494";
+ public static final Rule ruleOne = builder()
+ ._id(_ID_ONE)
+ .feature(WLM_STRING)
+ .label(LABEL_ONE)
+ .attributeMap(Map.of("index_pattern", List.of("pattern_1")))
+ .updatedAt(TIMESTAMP_ONE)
+ .build();
+
+ public static final Rule ruleTwo = builder()
+ ._id(_ID_TWO)
+ .feature(WLM_STRING)
+ .label(LABEL_TWO)
+ .attributeMap(Map.of("index_pattern", List.of("pattern_2", "pattern_3")))
+ .updatedAt(TIMESTAMP_TWO)
+ .build();
+
+ public static List ruleList() {
+ List list = new ArrayList<>();
+ list.add(ruleOne);
+ list.add(ruleTwo);
+ return list;
+ }
+//
+// public static ClusterState clusterState() {
+// final Metadata metadata = Metadata.builder().queryGroups(Map.of(_ID_ONE, queryGroupOne, _ID_TWO, queryGroupTwo)).build();
+// return ClusterState.builder(new ClusterName("_name")).metadata(metadata).build();
+// }
+//
+// public static Set> clusterSettingsSet() {
+// Set> set = new HashSet<>(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
+// set.add(QueryGroupPersistenceService.MAX_QUERY_GROUP_COUNT);
+// assertFalse(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS.contains(QueryGroupPersistenceService.MAX_QUERY_GROUP_COUNT));
+// return set;
+// }
+//
+// public static Settings settings() {
+// return Settings.builder().build();
+// }
+//
+// public static ClusterSettings clusterSettings() {
+// return new ClusterSettings(settings(), clusterSettingsSet());
+// }
+//
+// public static QueryGroupPersistenceService queryGroupPersistenceService() {
+// ClusterApplierService clusterApplierService = new ClusterApplierService(
+// "name",
+// settings(),
+// clusterSettings(),
+// mock(ThreadPool.class)
+// );
+// clusterApplierService.setInitialState(clusterState());
+// ClusterService clusterService = new ClusterService(
+// settings(),
+// clusterSettings(),
+// mock(ClusterManagerService.class),
+// clusterApplierService
+// );
+// return new QueryGroupPersistenceService(clusterService, settings(), clusterSettings());
+// }
+//
+// public static Tuple preparePersistenceServiceSetup(Map queryGroups) {
+// Metadata metadata = Metadata.builder().queryGroups(queryGroups).build();
+// Settings settings = Settings.builder().build();
+// ClusterState clusterState = ClusterState.builder(new ClusterName("_name")).metadata(metadata).build();
+// ClusterSettings clusterSettings = new ClusterSettings(settings, clusterSettingsSet());
+// ClusterApplierService clusterApplierService = new ClusterApplierService(
+// "name",
+// settings(),
+// clusterSettings(),
+// mock(ThreadPool.class)
+// );
+// clusterApplierService.setInitialState(clusterState);
+// ClusterService clusterService = new ClusterService(
+// settings(),
+// clusterSettings(),
+// mock(ClusterManagerService.class),
+// clusterApplierService
+// );
+// QueryGroupPersistenceService queryGroupPersistenceService = new QueryGroupPersistenceService(
+// clusterService,
+// settings,
+// clusterSettings
+// );
+// return new Tuple(queryGroupPersistenceService, clusterState);
+// }
+
+// public static void assertEqualResourceLimits(
+// Map resourceLimitMapOne,
+// Map resourceLimitMapTwo
+// ) {
+// assertTrue(resourceLimitMapOne.keySet().containsAll(resourceLimitMapTwo.keySet()));
+// assertTrue(resourceLimitMapOne.values().containsAll(resourceLimitMapTwo.values()));
+// }
+
+ public static void assertEqualRules(
+ Collection collectionOne,
+ Collection collectionTwo,
+ boolean ruleUpdated
+ ) {
+ assertEquals(collectionOne.size(), collectionTwo.size());
+ List listOne = new ArrayList<>(collectionOne);
+ List listTwo = new ArrayList<>(collectionTwo);
+ listOne.sort(Comparator.comparing(Rule::get_id));
+ listTwo.sort(Comparator.comparing(Rule::get_id));
+ for (int i = 0; i < listOne.size(); i++) {
+ if (ruleUpdated) {
+ Rule one = listOne.get(i);
+ Rule two = listTwo.get(i);
+ assertEquals(one.get_id(), two.get_id());
+ assertEquals(one.getFeature(), two.getFeature());
+ assertEquals(one.getLabel(), two.getLabel());
+ assertEquals(one.getAttributeMap(), two.getAttributeMap());
+ } else {
+ assertEquals(listOne.get(i), listTwo.get(i));
+ }
+ }
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/CreateQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupRequestTests.java
similarity index 96%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/CreateQueryGroupRequestTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupRequestTests.java
index dd9de4bf8fb1a..a20f027f09e15 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/CreateQueryGroupRequestTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupRequestTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.cluster.metadata.QueryGroup;
import org.opensearch.common.io.stream.BytesStreamOutput;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/CreateQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupResponseTests.java
similarity index 98%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/CreateQueryGroupResponseTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupResponseTests.java
index 3a2ce215d21b5..fb6141fc65082 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/CreateQueryGroupResponseTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/CreateQueryGroupResponseTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.cluster.metadata.QueryGroup;
import org.opensearch.common.io.stream.BytesStreamOutput;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupRequestTests.java
similarity index 96%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupRequestTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupRequestTests.java
index bc2e4f0faca4c..c91742cc3609a 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/DeleteQueryGroupRequestTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/DeleteQueryGroupRequestTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.common.io.stream.BytesStreamOutput;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/GetQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupRequestTests.java
similarity index 97%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/GetQueryGroupRequestTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupRequestTests.java
index 32b5f7ec9e2c3..3a96a58fe88ed 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/GetQueryGroupRequestTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupRequestTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.common.io.stream.BytesStreamOutput;
import org.opensearch.core.common.io.stream.StreamInput;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/GetQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupResponseTests.java
similarity index 99%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/GetQueryGroupResponseTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupResponseTests.java
index 1a2ac282d86a4..95c4422f92e5f 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/GetQueryGroupResponseTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/GetQueryGroupResponseTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.cluster.metadata.QueryGroup;
import org.opensearch.common.io.stream.BytesStreamOutput;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/QueryGroupActionTestUtils.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/QueryGroupActionTestUtils.java
similarity index 90%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/QueryGroupActionTestUtils.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/QueryGroupActionTestUtils.java
index 08d128ca7ed59..87c768b056e4e 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/QueryGroupActionTestUtils.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/QueryGroupActionTestUtils.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.wlm.MutableQueryGroupFragment;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/TransportDeleteQueryGroupActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/TransportDeleteQueryGroupActionTests.java
similarity index 94%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/TransportDeleteQueryGroupActionTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/TransportDeleteQueryGroupActionTests.java
index 39d263bfdb150..f1afbc67ab8f9 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/TransportDeleteQueryGroupActionTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/TransportDeleteQueryGroupActionTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.clustermanager.AcknowledgedResponse;
@@ -14,7 +14,7 @@
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.service.ClusterService;
import org.opensearch.core.action.ActionListener;
-import org.opensearch.plugin.wlm.service.QueryGroupPersistenceService;
+import org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService;
import org.opensearch.test.OpenSearchTestCase;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/TransportGetQueryGroupActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/TransportGetQueryGroupActionTests.java
similarity index 97%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/TransportGetQueryGroupActionTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/TransportGetQueryGroupActionTests.java
index 755b11a5f4b89..5ddd8ec4e29cc 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/TransportGetQueryGroupActionTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/TransportGetQueryGroupActionTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.ResourceNotFoundException;
import org.opensearch.action.support.ActionFilters;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupRequestTests.java
similarity index 98%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupRequestTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupRequestTests.java
index b99f079e81984..3175c0a812287 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupRequestTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupRequestTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.common.io.stream.BytesStreamOutput;
import org.opensearch.core.common.io.stream.StreamInput;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupResponseTests.java
similarity index 98%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupResponseTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupResponseTests.java
index a7ab4c6a682ef..3f0bde66699b1 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/action/UpdateQueryGroupResponseTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/action/UpdateQueryGroupResponseTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.action;
+package org.opensearch.plugin.wlm.querygroup.action;
import org.opensearch.cluster.metadata.QueryGroup;
import org.opensearch.common.io.stream.BytesStreamOutput;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/rest/RestDeleteQueryGroupActionTests.java
similarity index 94%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupActionTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/rest/RestDeleteQueryGroupActionTests.java
index 28ed813ec4130..598e262a5a9ed 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rest/RestDeleteQueryGroupActionTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/rest/RestDeleteQueryGroupActionTests.java
@@ -6,14 +6,14 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.rest;
+package org.opensearch.plugin.wlm.querygroup.rest;
import org.opensearch.action.support.clustermanager.AcknowledgedResponse;
import org.opensearch.client.node.NodeClient;
import org.opensearch.common.CheckedConsumer;
import org.opensearch.common.unit.TimeValue;
-import org.opensearch.plugin.wlm.action.DeleteQueryGroupAction;
-import org.opensearch.plugin.wlm.action.DeleteQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.DeleteQueryGroupAction;
+import org.opensearch.plugin.wlm.querygroup.action.DeleteQueryGroupRequest;
import org.opensearch.rest.RestChannel;
import org.opensearch.rest.RestHandler;
import org.opensearch.rest.RestRequest;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/service/QueryGroupPersistenceServiceTests.java
similarity index 97%
rename from plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java
rename to plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/service/QueryGroupPersistenceServiceTests.java
index 67e47be1a55ce..49993d18e05ab 100644
--- a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/service/QueryGroupPersistenceServiceTests.java
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/querygroup/service/QueryGroupPersistenceServiceTests.java
@@ -6,7 +6,7 @@
* compatible open source license.
*/
-package org.opensearch.plugin.wlm.service;
+package org.opensearch.plugin.wlm.querygroup.service;
import org.opensearch.ResourceNotFoundException;
import org.opensearch.action.support.clustermanager.AcknowledgedResponse;
@@ -22,10 +22,10 @@
import org.opensearch.common.settings.Settings;
import org.opensearch.core.action.ActionListener;
import org.opensearch.plugin.wlm.QueryGroupTestUtils;
-import org.opensearch.plugin.wlm.action.CreateQueryGroupResponse;
-import org.opensearch.plugin.wlm.action.DeleteQueryGroupRequest;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupRequest;
-import org.opensearch.plugin.wlm.action.UpdateQueryGroupResponse;
+import org.opensearch.plugin.wlm.querygroup.action.CreateQueryGroupResponse;
+import org.opensearch.plugin.wlm.querygroup.action.DeleteQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.UpdateQueryGroupResponse;
import org.opensearch.test.OpenSearchTestCase;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.wlm.MutableQueryGroupFragment;
@@ -58,9 +58,9 @@
import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupOne;
import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupPersistenceService;
import static org.opensearch.plugin.wlm.QueryGroupTestUtils.queryGroupTwo;
-import static org.opensearch.plugin.wlm.action.QueryGroupActionTestUtils.updateQueryGroupRequest;
-import static org.opensearch.plugin.wlm.service.QueryGroupPersistenceService.QUERY_GROUP_COUNT_SETTING_NAME;
-import static org.opensearch.plugin.wlm.service.QueryGroupPersistenceService.SOURCE;
+import static org.opensearch.plugin.wlm.querygroup.action.QueryGroupActionTestUtils.updateQueryGroupRequest;
+import static org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService.QUERY_GROUP_COUNT_SETTING_NAME;
+import static org.opensearch.plugin.wlm.querygroup.service.QueryGroupPersistenceService.SOURCE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyString;
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/CreateRuleRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/CreateRuleRequestTests.java
new file mode 100644
index 0000000000000..8eaa23d0127d2
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/CreateRuleRequestTests.java
@@ -0,0 +1,40 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.common.io.stream.BytesStreamOutput;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.test.OpenSearchTestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.opensearch.plugin.wlm.RuleTestUtils.ruleOne;
+import static org.opensearch.plugin.wlm.RuleTestUtils.assertEqualRules;
+
+public class CreateRuleRequestTests extends OpenSearchTestCase {
+
+ /**
+ * Test case to verify the serialization and deserialization of CreateRuleRequest.
+ */
+ public void testSerialization() throws IOException {
+ CreateRuleRequest request = new CreateRuleRequest(ruleOne);
+ BytesStreamOutput out = new BytesStreamOutput();
+ request.writeTo(out);
+ StreamInput streamInput = out.bytes().streamInput();
+ CreateRuleRequest otherRequest = new CreateRuleRequest(streamInput);
+ List list1 = new ArrayList<>();
+ List list2 = new ArrayList<>();
+ list1.add(ruleOne);
+ list2.add(otherRequest.getRule());
+ assertEqualRules(list1, list2, false);
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/CreateRuleResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/CreateRuleResponseTests.java
new file mode 100644
index 0000000000000..49306b0f67435
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/CreateRuleResponseTests.java
@@ -0,0 +1,64 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.common.io.stream.BytesStreamOutput;
+import org.opensearch.common.xcontent.json.JsonXContent;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.XContentBuilder;
+import org.opensearch.test.OpenSearchTestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+import static org.opensearch.plugin.wlm.RuleTestUtils.assertEqualRules;
+import static org.opensearch.plugin.wlm.RuleTestUtils.ruleOne;
+
+public class CreateRuleResponseTests extends OpenSearchTestCase {
+
+ /**
+ * Test case to verify serialization and deserialization of CreateRuleResponse
+ */
+ public void testSerialization() throws IOException {
+ CreateRuleResponse response = new CreateRuleResponse(ruleOne, RestStatus.OK);
+ BytesStreamOutput out = new BytesStreamOutput();
+ response.writeTo(out);
+ StreamInput streamInput = out.bytes().streamInput();
+ CreateRuleResponse otherResponse = new CreateRuleResponse(streamInput);
+ assertEquals(response.getRestStatus(), otherResponse.getRestStatus());
+ Rule responseRule = response.getRule();
+ Rule otherResponseRule = otherResponse.getRule();
+ List listOne = new ArrayList<>();
+ List listTwo = new ArrayList<>();
+ listOne.add(responseRule);
+ listTwo.add(otherResponseRule);
+ assertEqualRules(listOne, listTwo, false);
+ }
+
+ /**
+ * Test case to validate the toXContent method of CreateRuleResponse
+ */
+ public void testToXContentCreateRule() throws IOException {
+ XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint();
+ CreateRuleResponse response = new CreateRuleResponse(ruleOne, RestStatus.OK);
+ String actual = response.toXContent(builder, mock(ToXContent.Params.class)).toString();
+ String expected = "{\n"
+ + " \"_id\" : \"AgfUO5Ja9yfvhdONlYi3TQ==\",\n"
+ + " \"label\" : \"label_one\",\n"
+ + " \"feature\" : \"WLM\",\n"
+ + " \"updated_at\" : \"1738011537558\", \n"
+ + "}";
+ assertEquals(expected, actual);
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/GetRuleRequestTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/GetRuleRequestTests.java
new file mode 100644
index 0000000000000..38a9a5336f2ea
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/GetRuleRequestTests.java
@@ -0,0 +1,46 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.common.io.stream.BytesStreamOutput;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.test.OpenSearchTestCase;
+
+import java.io.IOException;
+
+import static org.opensearch.plugin.wlm.RuleTestUtils._ID_ONE;
+
+public class GetRuleRequestTests extends OpenSearchTestCase {
+
+ /**
+ * Test case to verify the serialization and deserialization of GetRuleRequest
+ */
+ public void testSerialization() throws IOException {
+ GetRuleRequest request = new GetRuleRequest(_ID_ONE);
+ assertEquals(_ID_ONE, request.get_id());
+ BytesStreamOutput out = new BytesStreamOutput();
+ request.writeTo(out);
+ StreamInput streamInput = out.bytes().streamInput();
+ GetRuleRequest otherRequest = new GetRuleRequest(streamInput);
+ assertEquals(request.get_id(), otherRequest.get_id());
+ }
+
+ /**
+ * Test case to verify the serialization and deserialization of GetRuleRequest when name is null
+ */
+ public void testSerializationWithNull() throws IOException {
+ GetRuleRequest request = new GetRuleRequest((String) null);
+ assertNull(request.get_id());
+ BytesStreamOutput out = new BytesStreamOutput();
+ request.writeTo(out);
+ StreamInput streamInput = out.bytes().streamInput();
+ GetRuleRequest otherRequest = new GetRuleRequest(streamInput);
+ assertEquals(request.get_id(), otherRequest.get_id());
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/GetRuleResponseTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/GetRuleResponseTests.java
new file mode 100644
index 0000000000000..9383033f67225
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/GetRuleResponseTests.java
@@ -0,0 +1,145 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.cluster.metadata.Rule;
+import org.opensearch.common.io.stream.BytesStreamOutput;
+import org.opensearch.common.xcontent.json.JsonXContent;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.core.xcontent.ToXContent;
+import org.opensearch.core.xcontent.XContentBuilder;
+import org.opensearch.test.OpenSearchTestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+import static org.opensearch.plugin.wlm.RuleTestUtils.ruleOne;
+import static org.opensearch.plugin.wlm.RuleTestUtils.ruleTwo;
+import static org.opensearch.plugin.wlm.RuleTestUtils.assertEqualRules;
+import static org.opensearch.plugin.wlm.RuleTestUtils.ruleList;
+
+public class GetRuleResponseTests extends OpenSearchTestCase {
+
+ /**
+ * Test case to verify the serialization and deserialization of GetRuleResponse
+ */
+ public void testSerializationSingleRule() throws IOException {
+ List list = new ArrayList<>();
+ list.add(ruleOne);
+ GetRuleResponse response = new GetRuleResponse(list, RestStatus.OK);
+ assertEquals(response.getRules(), list);
+
+ BytesStreamOutput out = new BytesStreamOutput();
+ response.writeTo(out);
+ StreamInput streamInput = out.bytes().streamInput();
+
+ GetRuleResponse otherResponse = new GetRuleResponse(streamInput);
+ assertEquals(response.getRestStatus(), otherResponse.getRestStatus());
+ assertEqualRules(response.getRules(), otherResponse.getRules(), false);
+ }
+
+ /**
+ * Test case to verify the serialization and deserialization of GetRuleResponse when the result contains multiple rules
+ */
+ public void testSerializationMultipleRule() throws IOException {
+ GetRuleResponse response = new GetRuleResponse(ruleList(), RestStatus.OK);
+ assertEquals(response.getRules(), ruleList());
+
+ BytesStreamOutput out = new BytesStreamOutput();
+ response.writeTo(out);
+ StreamInput streamInput = out.bytes().streamInput();
+
+ GetRuleResponse otherResponse = new GetRuleResponse(streamInput);
+ assertEquals(response.getRestStatus(), otherResponse.getRestStatus());
+ assertEquals(2, otherResponse.getRules().size());
+ assertEqualRules(response.getRules(), otherResponse.getRules(), false);
+ }
+
+ /**
+ * Test case to verify the serialization and deserialization of GetRuleResponse when the result is empty
+ */
+ public void testSerializationNull() throws IOException {
+ List list = new ArrayList<>();
+ GetRuleResponse response = new GetRuleResponse(list, RestStatus.OK);
+ assertEquals(response.getRules(), list);
+
+ BytesStreamOutput out = new BytesStreamOutput();
+ response.writeTo(out);
+ StreamInput streamInput = out.bytes().streamInput();
+
+ GetRuleResponse otherResponse = new GetRuleResponse(streamInput);
+ assertEquals(response.getRestStatus(), otherResponse.getRestStatus());
+ assertEquals(0, otherResponse.getRules().size());
+ }
+
+ /**
+ * Test case to verify the toXContent of GetRuleResponse
+ */
+ public void testToXContentGetSingleRule() throws IOException {
+ List ruleList = new ArrayList<>();
+ ruleList.add(ruleOne);
+ XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint();
+ GetRuleResponse response = new GetRuleResponse(ruleList, RestStatus.OK);
+ String actual = response.toXContent(builder, mock(ToXContent.Params.class)).toString();
+ String expected = "{\n"
+ + " \"rules\" : [\n"
+ + " {\n"
+ + " \"_id\" : \"AgfUO5Ja9yfvhdONlYi3TQ==\",\n"
+ + " \"label\" : \"label_one\",\n"
+ + " \"feature\" : \"WLM\",\n"
+ + " \"updated_at\" : \"1738011537558\", \n"
+ + " }\n"
+ + " ]\n"
+ + "}";
+ assertEquals(expected, actual);
+ }
+
+ /**
+ * Test case to verify the toXContent of GetRuleResponse when the result contains multiple rules
+ */
+ public void testToXContentGetMultipleRule() throws IOException {
+ List ruleList = new ArrayList<>();
+ ruleList.add(ruleOne);
+ ruleList.add(ruleTwo);
+ XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint();
+ GetRuleResponse response = new GetRuleResponse(ruleList, RestStatus.OK);
+ String actual = response.toXContent(builder, mock(ToXContent.Params.class)).toString();
+ String expected = "{\n"
+ + " \"rules\" : [\n"
+ + " {\n"
+ + " \"_id\" : \"AgfUO5Ja9yfvhdONlYi3TQ==\",\n"
+ + " \"label\" : \"label_one\",\n"
+ + " \"feature\" : \"WLM\",\n"
+ + " \"updated_at\" : \"1738011537558\", \n"
+ + " },\n"
+ + " {\n"
+ + " \"_id\" : \"G5iIq84j7eK1qIAAAAIH53=1\",\n"
+ + " \"label\" : \"label_two\",\n"
+ + " \"feature\" : \"WLM\",\n"
+ + " \"updated_at\" : \"1738013454494\", \n"
+ + " },\n"
+ + " ]\n"
+ + "}";
+ assertEquals(expected, actual);
+ }
+
+ /**
+ * Test case to verify toXContent of GetRuleResponse when the result contains zero Rule
+ */
+ public void testToXContentGetZeroRule() throws IOException {
+ XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint();
+ GetRuleResponse otherResponse = new GetRuleResponse(new ArrayList<>(), RestStatus.OK);
+ String actual = otherResponse.toXContent(builder, mock(ToXContent.Params.class)).toString();
+ String expected = "{\n" + " \"rules\" : [ ]\n" + "}";
+ assertEquals(expected, actual);
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/TransportGetQueryGroupActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/TransportGetQueryGroupActionTests.java
new file mode 100644
index 0000000000000..f04e1ba1409ed
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/action/TransportGetQueryGroupActionTests.java
@@ -0,0 +1,33 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.action;
+
+import org.opensearch.ResourceNotFoundException;
+import org.opensearch.action.support.ActionFilters;
+import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
+import org.opensearch.cluster.service.ClusterService;
+import org.opensearch.core.action.ActionListener;
+import org.opensearch.plugin.wlm.querygroup.action.GetQueryGroupRequest;
+import org.opensearch.plugin.wlm.querygroup.action.TransportGetQueryGroupAction;
+import org.opensearch.test.OpenSearchTestCase;
+import org.opensearch.threadpool.ThreadPool;
+import org.opensearch.transport.TransportService;
+
+import static org.mockito.Mockito.mock;
+import static org.opensearch.plugin.wlm.QueryGroupTestUtils.*;
+
+public class TransportGetQueryGroupActionTests extends OpenSearchTestCase {
+
+ /**
+ * Test case for ClusterManagerOperation function
+ */
+ @SuppressWarnings("unchecked")
+ public void testClusterManagerOperation() throws Exception {
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/rest/RestCreateRuleActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/rest/RestCreateRuleActionTests.java
new file mode 100644
index 0000000000000..1f78636dcd902
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/rest/RestCreateRuleActionTests.java
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.rest;
+
+import org.opensearch.rest.RestHandler;
+import org.opensearch.test.OpenSearchTestCase;
+import java.util.List;
+
+import static org.opensearch.rest.RestRequest.Method.POST;
+import static org.opensearch.rest.RestRequest.Method.PUT;
+
+public class RestCreateRuleActionTests extends OpenSearchTestCase {
+ /**
+ * Test case to validate the construction for RestCreateRuleAction
+ */
+ public void testConstruction() {
+ RestCreateRuleAction action = new RestCreateRuleAction();
+ assertNotNull(action);
+ assertEquals("create_rule", action.getName());
+ List routes = action.routes();
+ assertEquals(2, routes.size());
+ RestHandler.Route route = routes.get(0);
+ assertEquals(POST, route.getMethod());
+ assertEquals("_wlm/rule/", route.getPath());
+ route = routes.get(1);
+ assertEquals(PUT, route.getMethod());
+ assertEquals("_wlm/rule/", route.getPath());
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/rest/RestGetRuleActionTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/rest/RestGetRuleActionTests.java
new file mode 100644
index 0000000000000..d5edb62c8138b
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/rest/RestGetRuleActionTests.java
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.rest;
+
+import org.opensearch.rest.RestHandler;
+import org.opensearch.test.OpenSearchTestCase;
+
+import java.util.List;
+
+import static org.opensearch.rest.RestRequest.Method.GET;
+
+public class RestGetRuleActionTests extends OpenSearchTestCase {
+ /**
+ * Test case to validate the construction for RestGetRuleAction
+ */
+ public void testConstruction() {
+ RestGetRuleAction action = new RestGetRuleAction();
+ assertNotNull(action);
+ assertEquals("get_rule", action.getName());
+ List routes = action.routes();
+ assertEquals(2, routes.size());
+ RestHandler.Route route = routes.get(0);
+ assertEquals(GET, route.getMethod());
+ assertEquals("_wlm/rule/", route.getPath());
+ route = routes.get(1);
+ assertEquals(GET, route.getMethod());
+ assertEquals("_wlm/rule/{id}", route.getPath());
+ }
+}
diff --git a/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/service/QueryGroupPersistenceServiceTests.java b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/service/QueryGroupPersistenceServiceTests.java
new file mode 100644
index 0000000000000..bdedffbb19909
--- /dev/null
+++ b/plugins/workload-management/src/test/java/org/opensearch/plugin/wlm/rule/service/QueryGroupPersistenceServiceTests.java
@@ -0,0 +1,45 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.plugin.wlm.rule.service;
+
+import org.mockito.ArgumentCaptor;
+import org.opensearch.ResourceNotFoundException;
+import org.opensearch.action.support.master.AcknowledgedResponse;
+import org.opensearch.cluster.AckedClusterStateUpdateTask;
+import org.opensearch.cluster.ClusterName;
+import org.opensearch.cluster.ClusterState;
+import org.opensearch.cluster.ClusterStateUpdateTask;
+import org.opensearch.cluster.metadata.Metadata;
+import org.opensearch.cluster.metadata.QueryGroup;
+import org.opensearch.cluster.service.ClusterService;
+import org.opensearch.common.collect.Tuple;
+import org.opensearch.common.settings.ClusterSettings;
+import org.opensearch.common.settings.Settings;
+import org.opensearch.core.action.ActionListener;
+import org.opensearch.plugin.wlm.QueryGroupTestUtils;
+import org.opensearch.plugin.wlm.rule.action.CreateRuleResponse;
+import org.opensearch.test.OpenSearchTestCase;
+import org.opensearch.threadpool.ThreadPool;
+import org.opensearch.wlm.MutableQueryGroupFragment;
+import org.opensearch.wlm.MutableQueryGroupFragment.ResiliencyMode;
+import org.opensearch.wlm.ResourceType;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
+import static org.opensearch.cluster.metadata.QueryGroup.builder;
+import static org.opensearch.plugin.wlm.QueryGroupTestUtils.*;
+import static org.opensearch.plugin.wlm.querygroup.action.QueryGroupActionTestUtils.updateQueryGroupRequest;
+
+public class QueryGroupPersistenceServiceTests extends OpenSearchTestCase {
+
+}
diff --git a/server/src/main/java/org/opensearch/cluster/metadata/Rule.java b/server/src/main/java/org/opensearch/cluster/metadata/Rule.java
new file mode 100644
index 0000000000000..665d544fcb739
--- /dev/null
+++ b/server/src/main/java/org/opensearch/cluster/metadata/Rule.java
@@ -0,0 +1,335 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.cluster.metadata;
+
+import org.joda.time.Instant;
+import org.opensearch.cluster.AbstractDiffable;
+import org.opensearch.cluster.Diff;
+import org.opensearch.common.annotation.ExperimentalApi;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.xcontent.ToXContentObject;
+import org.opensearch.core.xcontent.XContentBuilder;
+import org.opensearch.core.xcontent.XContentParseException;
+import org.opensearch.core.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.*;
+
+import static org.opensearch.cluster.metadata.QueryGroup.isValid;
+
+/**
+ * Represents a Rule in the OpenSearch cluster metadata.
+ * A Rule contains attributes, a feature it belongs to, and metadata.
+ * Rules are used to define constraints or behaviors related to query execution.
+ */
+
+@ExperimentalApi
+public class Rule extends AbstractDiffable implements ToXContentObject {
+ private final String _id;
+ private final Map> attributeMap;
+ private final Feature feature;
+ private final String label;
+ private final String updatedAt;
+ public static final Map> featureAlloedAttributesMap = Map.of(
+ Feature.QUERY_GROUP, Set.of(RuleAttribute.INDEX_PATTERN)
+ );
+
+ public Rule(String _id, Map> attributeMap, String label, String updatedAt, Feature feature) {
+ requireNonNullOrEmpty(_id, "Rule _id can't be null or empty");
+ Objects.requireNonNull(feature, "Couldn't identify which feature the rule belongs to. Rule feature name can't be null.");
+ requireNonNullOrEmpty(label, feature.getName() + " value can't be null or empty");
+ requireNonNullOrEmpty(updatedAt, "Rule update time can't be null or empty");
+ if (attributeMap == null || attributeMap.isEmpty()) {
+ throw new IllegalArgumentException("Rule should have at least 1 attribute requirement");
+ }
+ if (!isValid(Instant.parse(updatedAt).getMillis())) {
+ throw new IllegalArgumentException("Rule update time is not a valid epoch");
+ }
+ validatedAttributeMap(attributeMap, feature);
+
+ this._id = _id;
+ this.attributeMap = attributeMap;
+ this.label = label;
+ this.updatedAt = updatedAt;
+ this.feature = feature;
+ }
+
+ public Rule(StreamInput in) throws IOException {
+ this(in.readString(),
+ in.readMap((i) -> RuleAttribute.fromName(i.readString()), StreamInput::readStringList),
+ in.readString(), in.readString(),
+ Feature.fromName(in.readString()));
+ }
+
+ public static void requireNonNullOrEmpty(String value, String message) {
+ if (value == null || value.isEmpty()) {
+ throw new IllegalArgumentException(message);
+ }
+ }
+
+ public static void validatedAttributeMap(Map> attributeMap, Feature feature) {
+ if (!featureAlloedAttributesMap.containsKey(feature)) {
+ throw new IllegalArgumentException("Couldn't find any valid attribute name under the feature: " + feature.getName());
+ }
+ Set ValidAttributesForFeature = featureAlloedAttributesMap.get(feature);
+ for (Map.Entry> entry : attributeMap.entrySet()) {
+ RuleAttribute ruleAttribute = entry.getKey();
+ List attributeValues = entry.getValue();
+ if (!ValidAttributesForFeature.contains(ruleAttribute)) {
+ throw new IllegalArgumentException(ruleAttribute.getName() + " is not a valid attribute name under the feature: " + feature.getName());
+ }
+ if (attributeValues.size() > 10) {
+ throw new IllegalArgumentException("Each attribute can only have a maximum of 10 values. The input attribute " + ruleAttribute + " exceeds this limit.");
+ }
+ for (String attributeValue: attributeValues) {
+ if (attributeValue.isEmpty()) {
+ throw new IllegalArgumentException("Attribute value should not be an empty string");
+ }
+ if (attributeValue.length() > 100) {
+ throw new IllegalArgumentException("Attribute value can only have a maximum of 100 characters. The input " + attributeValue + " exceeds this limit.");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeString(_id);
+ out.writeMap(attributeMap, RuleAttribute::writeTo, StreamOutput::writeStringCollection);
+ out.writeString(label);
+ out.writeString(updatedAt);
+ out.writeString(feature.getName());
+ }
+
+ public static Rule fromXContent(final XContentParser parser) throws IOException {
+ return Builder.fromXContent(parser).build();
+ }
+
+ public String get_id() {
+ return _id;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public Feature getFeature() {
+ return feature;
+ }
+
+ public Map> getAttributeMap() {
+ return attributeMap;
+ }
+
+ /**
+ * Enum representing possible attributes that a rule can have.
+ * Attributes define constraints or behaviors for rules.
+ */
+ @ExperimentalApi
+ public enum Feature {
+ QUERY_GROUP("query_group");
+
+ private final String name;
+
+ Feature(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static boolean isValidFeature(String s) {
+ for (Feature feature : values()) {
+ if (feature.getName().equalsIgnoreCase(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Feature fromName(String s) {
+ for (Feature feature : values()) {
+ if (feature.getName().equalsIgnoreCase(s)) return feature;
+
+ }
+ throw new IllegalArgumentException("Invalid value for Feature: " + s);
+ }
+ }
+
+ /**
+ * Enum representing different features that a rule can be associated with.
+ * Each feature defines a category of rules within OpenSearch.
+ */
+ @ExperimentalApi
+ public enum RuleAttribute {
+ INDEX_PATTERN("index_pattern");
+
+ private final String name;
+
+ RuleAttribute(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static void writeTo(StreamOutput out, RuleAttribute ruleAttribute) throws IOException {
+ out.writeString(ruleAttribute.getName());
+ }
+
+ public static RuleAttribute fromName(String s) {
+ for (RuleAttribute attribute : values()) {
+ if (attribute.getName().equalsIgnoreCase(s)) return attribute;
+
+ }
+ throw new IllegalArgumentException("Invalid value for RuleAttribute: " + s);
+ }
+ }
+
+ @Override
+ public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
+ builder.startObject();
+ builder.field("_id", _id);
+ for (Map.Entry> entry : attributeMap.entrySet()) {
+ builder.array(entry.getKey().getName(), entry.getValue().toArray(new String[0]));
+ }
+ builder.field(feature.getName(), label);
+ builder.field("updated_at", updatedAt);
+ builder.endObject();
+ return builder;
+ }
+
+ public XContentBuilder toXContentWithoutId(final XContentBuilder builder, final Params params) throws IOException {
+ builder.startObject();
+ for (Map.Entry> entry : attributeMap.entrySet()) {
+ builder.array(entry.getKey().getName(), entry.getValue().toArray(new String[0]));
+ }
+ builder.field(feature.getName(), label);
+ builder.field("updated_at", updatedAt);
+ builder.endObject();
+ return builder;
+ }
+
+ public static Diff readDiff(final StreamInput in) throws IOException {
+ return readDiffFrom(Rule::new, in);
+ }
+
+ /**
+ * empty builder method for the {@link Rule}
+ * @return Builder object
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * builder method for the {@link Rule}
+ * @return Builder object
+ */
+ public Builder builderFromRule() {
+ return new Builder()._id(_id).label(label).feature(feature.getName()).updatedAt(updatedAt).attributeMap(attributeMap);
+ }
+
+ /**
+ * Builder class for {@link Rule}
+ */
+ @ExperimentalApi
+ public static class Builder {
+ private String _id;
+ private Map> attributeMap;
+ private Feature feature;
+ private String label;
+ private String updatedAt;
+
+ private Builder() {}
+
+ public static Builder fromXContent(XContentParser parser) throws IOException {
+ if (parser.currentToken() == null) {
+ parser.nextToken();
+ }
+
+ Builder builder = builder();
+ XContentParser.Token token = parser.currentToken();
+
+ if (token != XContentParser.Token.START_OBJECT) {
+ throw new IllegalArgumentException("Expected START_OBJECT token but found [" + parser.currentName() + "]");
+ }
+ Map> attributeMap1 = new HashMap<>();
+ String fieldName = "";
+ while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
+ if (token == XContentParser.Token.FIELD_NAME) {
+ fieldName = parser.currentName();
+ } else if (token.isValue()) {
+ if (fieldName.equals("_id")) {
+ builder._id(parser.text());
+ } else if (Feature.isValidFeature(fieldName)) {
+ builder.feature(fieldName);
+ builder.label(parser.text());
+ } else if (fieldName.equals("updated_at")) {
+ builder.updatedAt(parser.text());
+ } else {
+ throw new IllegalArgumentException(fieldName + " is not a valid field in Rule");
+ }
+ } else if (token == XContentParser.Token.START_ARRAY) {
+ RuleAttribute ruleAttribute = RuleAttribute.fromName(fieldName);
+ List indexPatternList = new ArrayList<>();
+ while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
+ if (parser.currentToken() == XContentParser.Token.VALUE_STRING) {
+ indexPatternList.add(parser.text());
+ } else {
+ throw new XContentParseException("Unexpected token in array: " + parser.currentToken());
+ }
+ }
+ attributeMap1.put(ruleAttribute, indexPatternList);
+ }
+ }
+ return builder.attributeMap(attributeMap1);
+ }
+
+ public Builder _id(String _id) {
+ this._id = _id;
+ return this;
+ }
+
+ public Builder label(String label) {
+ this.label = label;
+ return this;
+ }
+
+ public Builder attributeMap(Map> attributeMap) {
+ this.attributeMap = attributeMap;
+ return this;
+ }
+
+ public Builder feature(String feature) {
+ this.feature = Feature.fromName(feature);
+ return this;
+ }
+
+ public Builder updatedAt(String updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
+ }
+
+ public Rule build() {
+ return new Rule(_id, attributeMap, label, updatedAt, feature);
+ }
+
+ public String getLabel() {
+ return label;
+ }
+ }
+}