diff --git a/src/main/kotlin/org/opensearch/replication/ReplicationPlugin.kt b/src/main/kotlin/org/opensearch/replication/ReplicationPlugin.kt index 09431d6e7..8766d4091 100644 --- a/src/main/kotlin/org/opensearch/replication/ReplicationPlugin.kt +++ b/src/main/kotlin/org/opensearch/replication/ReplicationPlugin.kt @@ -41,8 +41,8 @@ import org.opensearch.replication.action.status.ReplicationStatusAction import org.opensearch.replication.action.status.ShardsInfoAction import org.opensearch.replication.action.status.TranportShardsInfoAction import org.opensearch.replication.action.status.TransportReplicationStatusAction -import org.opensearch.replication.action.stop.StopIndexReplicationAction import org.opensearch.replication.action.stop.TransportStopIndexReplicationAction +import org.opensearch.replication.action.stop.TransportInternalStopIndexReplicationAction import org.opensearch.replication.action.update.TransportUpdateIndexReplicationAction import org.opensearch.replication.action.update.UpdateIndexReplicationAction import org.opensearch.replication.metadata.ReplicationMetadataManager @@ -99,6 +99,8 @@ import org.opensearch.common.util.concurrent.OpenSearchExecutors import org.opensearch.core.xcontent.NamedXContentRegistry import org.opensearch.core.xcontent.XContentParser import org.opensearch.commons.utils.OpenForTesting +import org.opensearch.commons.replication.action.ReplicationActions.INTERNAL_STOP_REPLICATION_ACTION_TYPE +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_TYPE import org.opensearch.env.Environment import org.opensearch.env.NodeEnvironment import org.opensearch.index.IndexModule @@ -233,7 +235,8 @@ internal class ReplicationPlugin : Plugin(), ActionPlugin, PersistentTaskPlugin, ActionHandler(GetFileChunkAction.INSTANCE, TransportGetFileChunkAction::class.java), ActionHandler(UpdateAutoFollowPatternAction.INSTANCE, TransportUpdateAutoFollowPatternAction::class.java), ActionHandler(AutoFollowClusterManagerNodeAction.INSTANCE, TransportAutoFollowClusterManagerNodeAction::class.java), - ActionHandler(StopIndexReplicationAction.INSTANCE, TransportStopIndexReplicationAction::class.java), + ActionHandler(STOP_REPLICATION_ACTION_TYPE, TransportStopIndexReplicationAction::class.java), + ActionHandler(INTERNAL_STOP_REPLICATION_ACTION_TYPE, TransportInternalStopIndexReplicationAction::class.java), ActionHandler(PauseIndexReplicationAction.INSTANCE, TransportPauseIndexReplicationAction::class.java), ActionHandler(ResumeIndexReplicationAction.INSTANCE, TransportResumeIndexReplicationAction::class.java), ActionHandler(UpdateIndexReplicationAction.INSTANCE, TransportUpdateIndexReplicationAction::class.java), diff --git a/src/main/kotlin/org/opensearch/replication/action/stop/StopIndexReplicationAction.kt b/src/main/kotlin/org/opensearch/replication/action/stop/StopIndexReplicationAction.kt deleted file mode 100644 index 5a35420d1..000000000 --- a/src/main/kotlin/org/opensearch/replication/action/stop/StopIndexReplicationAction.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.replication.action.stop - -import org.opensearch.action.ActionType -import org.opensearch.action.support.clustermanager.AcknowledgedResponse - -class StopIndexReplicationAction private constructor(): ActionType(NAME, ::AcknowledgedResponse) { - companion object { - const val NAME = "indices:admin/plugins/replication/index/stop" - val INSTANCE: StopIndexReplicationAction = StopIndexReplicationAction() - } -} diff --git a/src/main/kotlin/org/opensearch/replication/action/stop/StopIndexReplicationRequest.kt b/src/main/kotlin/org/opensearch/replication/action/stop/StopIndexReplicationRequest.kt deleted file mode 100644 index 12310d486..000000000 --- a/src/main/kotlin/org/opensearch/replication/action/stop/StopIndexReplicationRequest.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.replication.action.stop - -import org.opensearch.action.ActionRequestValidationException -import org.opensearch.action.IndicesRequest -import org.opensearch.action.support.IndicesOptions -import org.opensearch.core.ParseField -import org.opensearch.action.support.clustermanager.AcknowledgedRequest -import org.opensearch.core.common.io.stream.StreamInput -import org.opensearch.core.common.io.stream.StreamOutput -import org.opensearch.core.xcontent.* - -class StopIndexReplicationRequest : AcknowledgedRequest, IndicesRequest.Replaceable, ToXContentObject { - - lateinit var indexName: String - - constructor(indexName: String) { - this.indexName = indexName - } - - private constructor() { - } - - constructor(inp: StreamInput): super(inp) { - indexName = inp.readString() - } - - companion object { - private val PARSER = ObjectParser("StopReplicationRequestParser") { - StopIndexReplicationRequest() - } - - fun fromXContent(parser: XContentParser, followerIndex: String): StopIndexReplicationRequest { - val stopIndexReplicationRequest = PARSER.parse(parser, null) - stopIndexReplicationRequest.indexName = followerIndex - return stopIndexReplicationRequest - } - } - - override fun validate(): ActionRequestValidationException? { - return null - } - - override fun indices(vararg indices: String?): IndicesRequest { - return this - } - - override fun indices(): Array { - return arrayOf(indexName) - } - - override fun indicesOptions(): IndicesOptions { - return IndicesOptions.strictSingleIndexNoExpandForbidClosed() - } - - override fun toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder { - builder.startObject() - builder.field("indexName", indexName) - builder.endObject() - return builder - } - - override fun writeTo(out: StreamOutput) { - super.writeTo(out) - out.writeString(indexName) - } - -} \ No newline at end of file diff --git a/src/main/kotlin/org/opensearch/replication/action/stop/TransportInternalStopIndexReplicationAction.kt b/src/main/kotlin/org/opensearch/replication/action/stop/TransportInternalStopIndexReplicationAction.kt new file mode 100755 index 000000000..ed2058045 --- /dev/null +++ b/src/main/kotlin/org/opensearch/replication/action/stop/TransportInternalStopIndexReplicationAction.kt @@ -0,0 +1,78 @@ +/* + * 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. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.replication.action.stop + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.apache.logging.log4j.LogManager +import org.opensearch.action.support.HandledTransportAction +import org.opensearch.action.ActionRequest +import org.opensearch.action.support.ActionFilters +import org.opensearch.action.support.clustermanager.AcknowledgedResponse +import org.opensearch.transport.client.Client +import org.opensearch.common.inject.Inject +import org.opensearch.cluster.metadata.IndexNameExpressionResolver +import org.opensearch.cluster.service.ClusterService +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_TYPE +import org.opensearch.commons.replication.action.StopIndexReplicationRequest +import org.opensearch.commons.replication.action.ReplicationActions.INTERNAL_STOP_REPLICATION_ACTION_NAME +import org.opensearch.commons.utils.recreateObject +import org.opensearch.core.action.ActionListener +import org.opensearch.replication.metadata.ReplicationMetadataManager +import org.opensearch.replication.util.coroutineContext +import org.opensearch.replication.util.stackTraceToString +import org.opensearch.replication.util.suspendExecute +import org.opensearch.tasks.Task +import org.opensearch.threadpool.ThreadPool +import org.opensearch.transport.TransportService + +/* Internal transport action used by Index Management plugin to invoke stop replication + It transforms the request, and invokes the stop replication action (TransportStopIndexReplicationAction) on it. + */ +class TransportInternalStopIndexReplicationAction @Inject constructor ( + val name: String, + val transportService: TransportService, + val clusterService: ClusterService, + val threadPool: ThreadPool, + val client: Client, + val actionFilters: ActionFilters, + val indexNameExpressionResolver: IndexNameExpressionResolver, + val replicationMetadataManager: ReplicationMetadataManager, +): HandledTransportAction (INTERNAL_STOP_REPLICATION_ACTION_NAME, transportService, actionFilters, ::StopIndexReplicationRequest), + CoroutineScope by GlobalScope { + companion object { + private val log = LogManager.getLogger(TransportInternalStopIndexReplicationAction::class.java) + } + + @Throws(Exception::class) + override fun doExecute(task: Task?, request: ActionRequest?, listener: ActionListener?) { + launch(Dispatchers.Unconfined + threadPool.coroutineContext()) { + val transformedRequest = if (request is StopIndexReplicationRequest) { + request + } else { + request?.let { recreateObject(it) { StopIndexReplicationRequest(it) } } + ?: throw IllegalArgumentException("Request cannot be null") + } + + try { + val response = client.suspendExecute(STOP_REPLICATION_ACTION_TYPE, transformedRequest, true) + log.info("Stop replication successful for index[${transformedRequest.indexName}] with response: " + response.isAcknowledged) + listener?.onResponse(AcknowledgedResponse(true)) + } catch (e: Exception) { + log.error("Stop replication failed for index[${transformedRequest.indexName}] with error ${e.stackTraceToString()}") + listener?.onFailure(e) + } + } + } +} diff --git a/src/main/kotlin/org/opensearch/replication/action/stop/TransportStopIndexReplicationAction.kt b/src/main/kotlin/org/opensearch/replication/action/stop/TransportStopIndexReplicationAction.kt index 575e1e695..d6be76765 100644 --- a/src/main/kotlin/org/opensearch/replication/action/stop/TransportStopIndexReplicationAction.kt +++ b/src/main/kotlin/org/opensearch/replication/action/stop/TransportStopIndexReplicationAction.kt @@ -11,6 +11,8 @@ package org.opensearch.replication.action.stop +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_NAME +import org.opensearch.commons.replication.action.StopIndexReplicationRequest import org.opensearch.replication.ReplicationPlugin.Companion.REPLICATED_INDEX_SETTING import org.opensearch.replication.action.index.block.IndexBlockUpdateType import org.opensearch.replication.action.index.block.UpdateIndexBlockAction @@ -60,6 +62,15 @@ import org.opensearch.threadpool.ThreadPool import org.opensearch.transport.TransportService import java.io.IOException +/* + The classes StopIndexReplicationRequest and StopIndexReplicationAction have been moved from ccr to common-utils + and are imported here through org.opensearch.commons.replication. + This helps in making these classes re-usable by other plugins like ism. + PR details: + [1] https://github.com/opensearch-project/common-utils/pull/667 + [2] https://github.com/opensearch-project/cross-cluster-replication/pull/1391 + */ + class TransportStopIndexReplicationAction @Inject constructor(transportService: TransportService, clusterService: ClusterService, threadPool: ThreadPool, @@ -68,7 +79,7 @@ class TransportStopIndexReplicationAction @Inject constructor(transportService: IndexNameExpressionResolver, val client: Client, val replicationMetadataManager: ReplicationMetadataManager) : - TransportClusterManagerNodeAction (StopIndexReplicationAction.NAME, + TransportClusterManagerNodeAction (STOP_REPLICATION_ACTION_NAME, transportService, clusterService, threadPool, actionFilters, ::StopIndexReplicationRequest, indexNameExpressionResolver), CoroutineScope by GlobalScope { diff --git a/src/main/kotlin/org/opensearch/replication/rest/StopIndexReplicationHandler.kt b/src/main/kotlin/org/opensearch/replication/rest/StopIndexReplicationHandler.kt index b00ebf235..01e70b11d 100644 --- a/src/main/kotlin/org/opensearch/replication/rest/StopIndexReplicationHandler.kt +++ b/src/main/kotlin/org/opensearch/replication/rest/StopIndexReplicationHandler.kt @@ -11,8 +11,8 @@ package org.opensearch.replication.rest -import org.opensearch.replication.action.stop.StopIndexReplicationAction -import org.opensearch.replication.action.stop.StopIndexReplicationRequest +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_TYPE +import org.opensearch.commons.replication.action.StopIndexReplicationRequest import org.opensearch.transport.client.node.NodeClient import org.opensearch.rest.BaseRestHandler import org.opensearch.rest.RestChannel @@ -38,7 +38,7 @@ class StopIndexReplicationHandler : BaseRestHandler() { val stopReplicationRequest = StopIndexReplicationRequest.fromXContent(parser, followIndex) return RestChannelConsumer { channel: RestChannel? -> client.admin().cluster() - .execute(StopIndexReplicationAction.INSTANCE, stopReplicationRequest, RestToXContentListener(channel)) + .execute(STOP_REPLICATION_ACTION_TYPE, stopReplicationRequest, RestToXContentListener(channel)) } } } diff --git a/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt b/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt index f811324a7..4eb607fcf 100644 --- a/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt +++ b/src/main/kotlin/org/opensearch/replication/util/SecurityContext.kt @@ -20,13 +20,14 @@ import org.opensearch.replication.action.repository.GetFileChunkAction import org.opensearch.replication.action.repository.GetStoreMetadataAction import org.opensearch.replication.action.resume.ResumeIndexReplicationAction import org.opensearch.replication.action.status.ReplicationStatusAction -import org.opensearch.replication.action.stop.StopIndexReplicationAction import org.opensearch.replication.action.update.UpdateIndexReplicationAction import org.opensearch.replication.metadata.ReplicationMetadataManager import org.opensearch.replication.metadata.store.ReplicationMetadata import org.opensearch.replication.metadata.store.ReplicationStoreMetadataType import org.opensearch.commons.ConfigConstants import org.opensearch.commons.authuser.User +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_NAME +import org.opensearch.commons.replication.action.ReplicationActions.INTERNAL_STOP_REPLICATION_ACTION_NAME import org.apache.logging.log4j.LogManager import org.opensearch.action.ActionRequest import org.opensearch.core.action.ActionResponse @@ -49,7 +50,7 @@ class SecurityContext { val LEADER_USER_ACTIONS = listOf(GetChangesAction.NAME, GetFileChunkAction.NAME) val FOLLOWER_USER_ACTIONS = listOf(ReplayChangesAction.NAME, ReplicateIndexAction.NAME, PauseIndexReplicationAction.NAME, - ResumeIndexReplicationAction.NAME, StopIndexReplicationAction.NAME, + ResumeIndexReplicationAction.NAME, STOP_REPLICATION_ACTION_NAME, INTERNAL_STOP_REPLICATION_ACTION_NAME, UpdateIndexReplicationAction.NAME, ReplicationStatusAction.NAME, UpdateAutoFollowPatternAction.NAME) diff --git a/src/test/kotlin/org/opensearch/replication/MultiClusterRestTestCase.kt b/src/test/kotlin/org/opensearch/replication/MultiClusterRestTestCase.kt index 185cadc42..57b54758f 100644 --- a/src/test/kotlin/org/opensearch/replication/MultiClusterRestTestCase.kt +++ b/src/test/kotlin/org/opensearch/replication/MultiClusterRestTestCase.kt @@ -11,6 +11,7 @@ package org.opensearch.replication +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_NAME import org.opensearch.replication.MultiClusterAnnotations.ClusterConfiguration import org.opensearch.replication.MultiClusterAnnotations.ClusterConfigurations import org.opensearch.replication.MultiClusterAnnotations.getAnnotationsFromClass @@ -329,7 +330,7 @@ abstract class MultiClusterRestTestCase : OpenSearchTestCase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] diff --git a/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityBase.kt b/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityBase.kt index 515893e2f..b370cc435 100644 --- a/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityBase.kt +++ b/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityBase.kt @@ -17,6 +17,7 @@ import org.apache.hc.core5.http.ContentType import org.apache.hc.core5.http.io.entity.StringEntity import org.opensearch.client.Request import org.junit.BeforeClass +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_NAME const val INTEG_TEST_PASSWORD = "ccr-integ-test@123" @@ -74,7 +75,7 @@ abstract class SecurityBase : MultiClusterRestTestCase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] @@ -106,7 +107,7 @@ abstract class SecurityBase : MultiClusterRestTestCase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] @@ -119,7 +120,7 @@ abstract class SecurityBase : MultiClusterRestTestCase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] @@ -151,7 +152,7 @@ abstract class SecurityBase : MultiClusterRestTestCase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] @@ -183,7 +184,7 @@ abstract class SecurityBase : MultiClusterRestTestCase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] @@ -257,7 +258,7 @@ abstract class SecurityBase : MultiClusterRestTestCase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] diff --git a/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityCustomRolesIT.kt b/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityCustomRolesIT.kt index bdb7e44d0..db9ce5a15 100644 --- a/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityCustomRolesIT.kt +++ b/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityCustomRolesIT.kt @@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit import org.opensearch.replication.task.autofollow.AutoFollowExecutor import org.opensearch.tasks.TaskInfo import org.junit.Before +import org.opensearch.commons.replication.action.ReplicationActions.STOP_REPLICATION_ACTION_NAME @MultiClusterAnnotations.ClusterConfigurations( MultiClusterAnnotations.ClusterConfiguration(clusterName = LEADER), @@ -413,7 +414,7 @@ class SecurityCustomRolesIT: SecurityBase() { "indices:admin/plugins/replication/index/start", "indices:admin/plugins/replication/index/pause", "indices:admin/plugins/replication/index/resume", - "indices:admin/plugins/replication/index/stop", + "$STOP_REPLICATION_ACTION_NAME", "indices:admin/plugins/replication/index/update", "indices:admin/plugins/replication/index/status_check" ] diff --git a/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityDlsFlsIT.kt b/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityDlsFlsIT.kt index b8ababe83..145c5893d 100644 --- a/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityDlsFlsIT.kt +++ b/src/test/kotlin/org/opensearch/replication/integ/rest/SecurityDlsFlsIT.kt @@ -1,4 +1,4 @@ -/* +/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to