Skip to content

Commit 3281a33

Browse files
committed
Refactor checks to ML Indices to return true when MultiTenancy enabled (opensearch-project#4089)
* refactor checks to ml indices to return true when MultiTenancy enabled Signed-off-by: Brian Flores <iflorbri@amazon.com> * add JavaDoc to doesMultiTenantIndexExists Signed-off-by: Brian Flores <iflorbri@amazon.com> * updates naming & adds UTs to doesMultiTenantIndexExist Signed-off-by: Brian Flores <iflorbri@amazon.com> * assert MLIndicesHandler has non-null MLFeatureEnabledSettingObject Signed-off-by: Brian Flores <iflorbri@amazon.com> * update JavaDoc with better grammar Signed-off-by: Brian Flores <iflorbri@amazon.com> * apply spotless Signed-off-by: Brian Flores <iflorbri@amazon.com> --------- Signed-off-by: Brian Flores <iflorbri@amazon.com>
1 parent e65f356 commit 3281a33

File tree

10 files changed

+119
-18
lines changed

10 files changed

+119
-18
lines changed

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/agent/MLAgentExecutor.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@
4343
import org.opensearch.ml.common.output.model.ModelTensor;
4444
import org.opensearch.ml.common.output.model.ModelTensorOutput;
4545
import org.opensearch.ml.common.output.model.ModelTensors;
46+
import org.opensearch.ml.common.settings.MLFeatureEnabledSetting;
4647
import org.opensearch.ml.common.settings.SettingsChangeListener;
4748
import org.opensearch.ml.common.spi.memory.Memory;
4849
import org.opensearch.ml.common.spi.tools.Tool;
4950
import org.opensearch.ml.engine.Executable;
5051
import org.opensearch.ml.engine.annotation.Function;
52+
import org.opensearch.ml.engine.encryptor.Encryptor;
53+
import org.opensearch.ml.engine.indices.MLIndicesHandler;
5154
import org.opensearch.ml.engine.memory.ConversationIndexMemory;
5255
import org.opensearch.ml.engine.memory.ConversationIndexMessage;
5356
import org.opensearch.ml.memory.action.conversation.CreateInteractionResponse;
@@ -85,6 +88,8 @@ public class MLAgentExecutor implements Executable, SettingsChangeListener {
8588
private Map<String, Tool.Factory> toolFactories;
8689
private Map<String, Memory.Factory> memoryFactoryMap;
8790
private volatile Boolean isMultiTenancyEnabled;
91+
private Encryptor encryptor;
92+
private MLFeatureEnabledSetting mlFeatureEnabledSetting;
8893

8994
public MLAgentExecutor(
9095
Client client,
@@ -94,7 +99,8 @@ public MLAgentExecutor(
9499
NamedXContentRegistry xContentRegistry,
95100
Map<String, Tool.Factory> toolFactories,
96101
Map<String, Memory.Factory> memoryFactoryMap,
97-
Boolean isMultiTenancyEnabled
102+
MLFeatureEnabledSetting mlFeatureEnabledSetting,
103+
Encryptor encryptor
98104
) {
99105
this.client = client;
100106
this.sdkClient = sdkClient;
@@ -103,7 +109,9 @@ public MLAgentExecutor(
103109
this.xContentRegistry = xContentRegistry;
104110
this.toolFactories = toolFactories;
105111
this.memoryFactoryMap = memoryFactoryMap;
106-
this.isMultiTenancyEnabled = isMultiTenancyEnabled;
112+
this.mlFeatureEnabledSetting = mlFeatureEnabledSetting;
113+
this.encryptor = encryptor;
114+
this.isMultiTenancyEnabled = mlFeatureEnabledSetting.isMultiTenancyEnabled();
107115
}
108116

109117
@Override
@@ -142,7 +150,7 @@ public void execute(Input input, ActionListener<Output> listener) {
142150
.fetchSourceContext(fetchSourceContext)
143151
.build();
144152

145-
if (clusterService.state().metadata().hasIndex(ML_AGENT_INDEX)) {
153+
if (MLIndicesHandler.doesMultiTenantIndexExist(clusterService, mlFeatureEnabledSetting.isMultiTenancyEnabled(), ML_AGENT_INDEX)) {
146154
try (ThreadContext.StoredContext context = client.threadPool().getThreadContext().stashContext()) {
147155
sdkClient
148156
.getDataObjectAsync(getDataObjectRequest, client.threadPool().executor("opensearch_ml_general"))

ml-algorithms/src/main/java/org/opensearch/ml/engine/indices/MLIndicesHandler.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@
3131
import org.opensearch.ml.common.CommonValue;
3232
import org.opensearch.ml.common.MLIndex;
3333
import org.opensearch.ml.common.exception.MLException;
34+
import org.opensearch.ml.common.settings.MLFeatureEnabledSetting;
35+
36+
import com.google.common.annotations.VisibleForTesting;
3437

3538
import lombok.AccessLevel;
39+
import lombok.NonNull;
3640
import lombok.RequiredArgsConstructor;
3741
import lombok.experimental.FieldDefaults;
3842
import lombok.extern.log4j.Log4j2;
@@ -41,9 +45,12 @@
4145
@RequiredArgsConstructor
4246
@Log4j2
4347
public class MLIndicesHandler {
44-
48+
@NonNull
4549
ClusterService clusterService;
50+
@NonNull
4651
Client client;
52+
@NonNull
53+
MLFeatureEnabledSetting mlFeatureEnabledSetting;
4754
private static final Map<String, AtomicBoolean> indexMappingUpdated = new HashMap<>();
4855

4956
static {
@@ -52,6 +59,21 @@ public class MLIndicesHandler {
5259
}
5360
}
5461

62+
/**
63+
* Determines whether an index exists on non-multi tenancy enabled environments. Otherwise,
64+
* returns true when multiTenancy is Enabled
65+
*
66+
* @param clusterService the cluster service
67+
* @param isMultiTenancyEnabled whether multi-tenancy is enabled
68+
* @param indexName - the index to search
69+
* @return boolean indicating the existence of an index. Returns true if multitenancy is enabled.
70+
* @implNote This method assumes if your environment enables multi tenancy, then your plugin indices are
71+
* pre-populated. If this is incorrect, it will result in unwanted early returns without checking the clusterService.
72+
*/
73+
public static boolean doesMultiTenantIndexExist(ClusterService clusterService, boolean isMultiTenancyEnabled, String indexName) {
74+
return isMultiTenancyEnabled || clusterService.state().metadata().hasIndex(indexName);
75+
}
76+
5577
public void initModelGroupIndexIfAbsent(ActionListener<Boolean> listener) {
5678
initMLIndexIfAbsent(MLIndex.MODEL_GROUP, listener);
5779
}
@@ -93,7 +115,7 @@ public void initMLIndexIfAbsent(MLIndex index, ActionListener<Boolean> listener)
93115
String mapping = index.getMapping();
94116
try (ThreadContext.StoredContext threadContext = client.threadPool().getThreadContext().stashContext()) {
95117
ActionListener<Boolean> internalListener = ActionListener.runBefore(listener, () -> threadContext.restore());
96-
if (!clusterService.state().metadata().hasIndex(indexName)) {
118+
if (!MLIndicesHandler.doesMultiTenantIndexExist(clusterService, mlFeatureEnabledSetting.isMultiTenancyEnabled(), indexName)) {
97119
ActionListener<CreateIndexResponse> actionListener = ActionListener.wrap(r -> {
98120
if (r.isAcknowledged()) {
99121
log.info("create index:{}", indexName);
@@ -208,4 +230,9 @@ public void shouldUpdateIndex(String indexName, Integer newVersion, ActionListen
208230
listener.onResponse(newVersion > oldVersion);
209231
}
210232

233+
@VisibleForTesting
234+
public boolean doesIndexExists(String indexName) {
235+
return MLIndicesHandler.doesMultiTenantIndexExist(clusterService, mlFeatureEnabledSetting.isMultiTenancyEnabled(), indexName);
236+
}
237+
211238
}

ml-algorithms/src/test/java/org/opensearch/ml/engine/indices/MLIndicesHandlerTest.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.opensearch.ml.engine.indices;
22

33
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertTrue;
46
import static org.mockito.ArgumentMatchers.any;
57
import static org.mockito.ArgumentMatchers.anyString;
68
import static org.mockito.ArgumentMatchers.isA;
@@ -11,6 +13,7 @@
1113
import static org.mockito.Mockito.when;
1214
import static org.opensearch.ml.common.CommonValue.META;
1315
import static org.opensearch.ml.common.CommonValue.ML_AGENT_INDEX;
16+
import static org.opensearch.ml.common.CommonValue.ML_CONFIG_INDEX;
1417
import static org.opensearch.ml.common.CommonValue.ML_MEMORY_MESSAGE_INDEX;
1518
import static org.opensearch.ml.common.CommonValue.ML_MEMORY_META_INDEX;
1619
import static org.opensearch.ml.common.CommonValue.SCHEMA_VERSION_FIELD;
@@ -37,6 +40,7 @@
3740
import org.opensearch.common.settings.Settings;
3841
import org.opensearch.common.util.concurrent.ThreadContext;
3942
import org.opensearch.core.action.ActionListener;
43+
import org.opensearch.ml.common.settings.MLFeatureEnabledSetting;
4044
import org.opensearch.threadpool.ThreadPool;
4145

4246
public class MLIndicesHandlerTest {
@@ -73,6 +77,9 @@ public class MLIndicesHandlerTest {
7377
@Mock
7478
private ThreadPool threadPool;
7579

80+
@Mock
81+
private MLFeatureEnabledSetting mlFeatureEnabledSetting;
82+
7683
Settings settings;
7784
ThreadContext threadContext;
7885
MLIndicesHandler indicesHandler;
@@ -101,7 +108,29 @@ public void setUp() {
101108
threadContext = new ThreadContext(settings);
102109
when(client.threadPool()).thenReturn(threadPool);
103110
when(threadPool.getThreadContext()).thenReturn(threadContext);
104-
indicesHandler = new MLIndicesHandler(clusterService, client);
111+
indicesHandler = new MLIndicesHandler(clusterService, client, mlFeatureEnabledSetting);
112+
}
113+
114+
@Test
115+
public void doesMultiTenantIndexExist_multiTenancyEnabled_returnsTrue() {
116+
assertTrue(MLIndicesHandler.doesMultiTenantIndexExist(null, true, null));
117+
MLIndicesHandler mlIndicesHandler = new MLIndicesHandler(clusterService, client, mlFeatureEnabledSetting);
118+
assertTrue(mlIndicesHandler.doesIndexExists(ML_CONFIG_INDEX));
119+
}
120+
121+
@Test
122+
public void doesMultiTenantIndexExist_multiTenancyDisabledSearchesClusterService_returnsValidSearchResult() {
123+
assertFalse(MLIndicesHandler.doesMultiTenantIndexExist(clusterService, false, null));
124+
125+
String sampleIndexName = "test-index";
126+
when(mlFeatureEnabledSetting.isMultiTenancyEnabled()).thenReturn(false);
127+
MLIndicesHandler mlIndicesHandler = new MLIndicesHandler(clusterService, client, mlFeatureEnabledSetting);
128+
129+
when(clusterService.state().metadata().hasIndex(sampleIndexName)).thenReturn(true);
130+
assertTrue(mlIndicesHandler.doesIndexExists(sampleIndexName));
131+
132+
when(clusterService.state().metadata().hasIndex(sampleIndexName)).thenReturn(false);
133+
assertFalse(mlIndicesHandler.doesIndexExists(sampleIndexName));
105134
}
106135

107136
@Test

plugin/src/main/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportAction.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
import org.opensearch.core.xcontent.NamedXContentRegistry;
2020
import org.opensearch.ml.common.connector.Connector;
2121
import org.opensearch.ml.common.connector.ConnectorAction;
22+
import org.opensearch.ml.common.settings.MLFeatureEnabledSetting;
2223
import org.opensearch.ml.common.transport.MLTaskResponse;
2324
import org.opensearch.ml.common.transport.connector.MLConnectorDeleteRequest;
2425
import org.opensearch.ml.common.transport.connector.MLExecuteConnectorAction;
2526
import org.opensearch.ml.common.transport.connector.MLExecuteConnectorRequest;
2627
import org.opensearch.ml.engine.MLEngineClassLoader;
2728
import org.opensearch.ml.engine.algorithms.remote.RemoteConnectorExecutor;
2829
import org.opensearch.ml.engine.encryptor.EncryptorImpl;
30+
import org.opensearch.ml.engine.indices.MLIndicesHandler;
2931
import org.opensearch.ml.helper.ConnectorAccessControlHelper;
3032
import org.opensearch.script.ScriptService;
3133
import org.opensearch.tasks.Task;
@@ -43,6 +45,7 @@ public class ExecuteConnectorTransportAction extends HandledTransportAction<Acti
4345

4446
ConnectorAccessControlHelper connectorAccessControlHelper;
4547
EncryptorImpl encryptor;
48+
MLFeatureEnabledSetting mlFeatureEnabledSetting;
4649

4750
@Inject
4851
public ExecuteConnectorTransportAction(
@@ -53,7 +56,8 @@ public ExecuteConnectorTransportAction(
5356
ScriptService scriptService,
5457
NamedXContentRegistry xContentRegistry,
5558
ConnectorAccessControlHelper connectorAccessControlHelper,
56-
EncryptorImpl encryptor
59+
EncryptorImpl encryptor,
60+
MLFeatureEnabledSetting mlFeatureEnabledSetting
5761
) {
5862
super(MLExecuteConnectorAction.NAME, transportService, actionFilters, MLConnectorDeleteRequest::new);
5963
this.client = client;
@@ -62,6 +66,7 @@ public ExecuteConnectorTransportAction(
6266
this.xContentRegistry = xContentRegistry;
6367
this.connectorAccessControlHelper = connectorAccessControlHelper;
6468
this.encryptor = encryptor;
69+
this.mlFeatureEnabledSetting = mlFeatureEnabledSetting;
6570
}
6671

6772
@Override
@@ -70,7 +75,8 @@ protected void doExecute(Task task, ActionRequest request, ActionListener<MLTask
7075
String connectorId = executeConnectorRequest.getConnectorId();
7176
String connectorAction = ConnectorAction.ActionType.EXECUTE.name();
7277

73-
if (clusterService.state().metadata().hasIndex(ML_CONNECTOR_INDEX)) {
78+
if (MLIndicesHandler
79+
.doesMultiTenantIndexExist(clusterService, mlFeatureEnabledSetting.isMultiTenancyEnabled(), ML_CONNECTOR_INDEX)) {
7480
ActionListener<Connector> listener = ActionListener.wrap(connector -> {
7581
if (connectorAccessControlHelper.validateConnectorAccess(client, connector)) {
7682
// adding tenantID as null, because we are not implement multi-tenancy for this feature yet.

plugin/src/main/java/org/opensearch/ml/action/handler/MLSearchHandler.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.opensearch.ml.common.connector.HttpConnector;
4141
import org.opensearch.ml.common.exception.MLException;
4242
import org.opensearch.ml.common.exception.MLResourceNotFoundException;
43+
import org.opensearch.ml.common.settings.MLFeatureEnabledSetting;
44+
import org.opensearch.ml.engine.indices.MLIndicesHandler;
4345
import org.opensearch.ml.helper.ModelAccessControlHelper;
4446
import org.opensearch.ml.utils.RestActionUtils;
4547
import org.opensearch.remote.metadata.client.SdkClient;
@@ -64,17 +66,20 @@ public class MLSearchHandler {
6466
private ModelAccessControlHelper modelAccessControlHelper;
6567

6668
private ClusterService clusterService;
69+
private MLFeatureEnabledSetting mlFeatureEnabledSetting;
6770

6871
public MLSearchHandler(
6972
Client client,
7073
NamedXContentRegistry xContentRegistry,
7174
ModelAccessControlHelper modelAccessControlHelper,
72-
ClusterService clusterService
75+
ClusterService clusterService,
76+
MLFeatureEnabledSetting mlFeatureEnabledSetting
7377
) {
7478
this.modelAccessControlHelper = modelAccessControlHelper;
7579
this.client = client;
7680
this.xContentRegistry = xContentRegistry;
7781
this.clusterService = clusterService;
82+
this.mlFeatureEnabledSetting = mlFeatureEnabledSetting;
7883
}
7984

8085
/**
@@ -131,7 +136,12 @@ public void search(SdkClient sdkClient, SearchRequest request, String tenantId,
131136
final ActionListener<SearchResponse> doubleWrapperListener = ActionListener
132137
.wrap(wrappedListener::onResponse, e -> wrapListenerToHandleSearchIndexNotFound(e, wrappedListener));
133138
if (modelAccessControlHelper.skipModelAccessControl(user)
134-
|| !clusterService.state().metadata().hasIndex(CommonValue.ML_MODEL_GROUP_INDEX)) {
139+
|| !MLIndicesHandler
140+
.doesMultiTenantIndexExist(
141+
clusterService,
142+
mlFeatureEnabledSetting.isMultiTenancyEnabled(),
143+
CommonValue.ML_MODEL_GROUP_INDEX
144+
)) {
135145

136146
SearchDataObjectRequest searchDataObjectRequest = SearchDataObjectRequest
137147
.builder()

plugin/src/main/java/org/opensearch/ml/action/tasks/CancelBatchJobTransportAction.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import org.opensearch.ml.engine.algorithms.remote.ConnectorUtils;
5757
import org.opensearch.ml.engine.algorithms.remote.RemoteConnectorExecutor;
5858
import org.opensearch.ml.engine.encryptor.EncryptorImpl;
59+
import org.opensearch.ml.engine.indices.MLIndicesHandler;
5960
import org.opensearch.ml.helper.ConnectorAccessControlHelper;
6061
import org.opensearch.ml.helper.ModelAccessControlHelper;
6162
import org.opensearch.ml.model.MLModelManager;
@@ -199,7 +200,12 @@ private void processRemoteBatchPrediction(MLTask mlTask, ActionListener<MLCancel
199200
if (model.getConnector() != null) {
200201
Connector connector = model.getConnector();
201202
executeConnector(connector, mlInput, actionListener);
202-
} else if (clusterService.state().metadata().hasIndex(ML_CONNECTOR_INDEX)) {
203+
} else if (MLIndicesHandler
204+
.doesMultiTenantIndexExist(
205+
clusterService,
206+
mlFeatureEnabledSetting.isMultiTenancyEnabled(),
207+
ML_CONNECTOR_INDEX
208+
)) {
203209
ActionListener<Connector> listener = ActionListener
204210
.wrap(connector -> { executeConnector(connector, mlInput, actionListener); }, e -> {
205211
log.error("Failed to get connector {}", model.getConnectorId(), e);

plugin/src/main/java/org/opensearch/ml/action/tasks/GetTaskTransportAction.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
import org.opensearch.ml.engine.algorithms.remote.ConnectorUtils;
8484
import org.opensearch.ml.engine.algorithms.remote.RemoteConnectorExecutor;
8585
import org.opensearch.ml.engine.encryptor.EncryptorImpl;
86+
import org.opensearch.ml.engine.indices.MLIndicesHandler;
8687
import org.opensearch.ml.engine.utils.S3Utils;
8788
import org.opensearch.ml.helper.ConnectorAccessControlHelper;
8889
import org.opensearch.ml.helper.ModelAccessControlHelper;
@@ -390,7 +391,12 @@ private void processRemoteBatchPrediction(
390391
remoteJob,
391392
actionListener
392393
);
393-
} else if (clusterService.state().metadata().hasIndex(ML_CONNECTOR_INDEX)) {
394+
} else if (MLIndicesHandler
395+
.doesMultiTenantIndexExist(
396+
clusterService,
397+
mlFeatureEnabledSetting.isMultiTenancyEnabled(),
398+
ML_CONNECTOR_INDEX
399+
)) {
394400
ActionListener<Connector> listener = ActionListener.wrap(connector -> {
395401
executeConnector(
396402
connector,

plugin/src/main/java/org/opensearch/ml/plugin/MachineLearningPlugin.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,9 @@ public Collection<Object> createComponents(
497497
Path dataPath = environment.dataFiles()[0];
498498
Path configFile = environment.configFile();
499499

500-
mlIndicesHandler = new MLIndicesHandler(clusterService, client);
500+
mlFeatureEnabledSetting = new MLFeatureEnabledSetting(clusterService, settings);
501+
502+
mlIndicesHandler = new MLIndicesHandler(clusterService, client, mlFeatureEnabledSetting);
501503

502504
SdkClient sdkClient = SdkClientFactory
503505
.createSdkClient(
@@ -562,7 +564,7 @@ public Collection<Object> createComponents(
562564
mlInputDatasetHandler = new MLInputDatasetHandler(client);
563565
modelAccessControlHelper = new ModelAccessControlHelper(clusterService, settings);
564566
connectorAccessControlHelper = new ConnectorAccessControlHelper(clusterService, settings);
565-
mlFeatureEnabledSetting = new MLFeatureEnabledSetting(clusterService, settings);
567+
566568
mlModelManager = new MLModelManager(
567569
clusterService,
568570
scriptService,
@@ -679,7 +681,8 @@ public Collection<Object> createComponents(
679681
xContentRegistry,
680682
toolFactories,
681683
memoryFactoryMap,
682-
mlFeatureEnabledSetting.isMultiTenancyEnabled()
684+
mlFeatureEnabledSetting,
685+
encryptor
683686
);
684687
MLEngineClassLoader.register(FunctionName.LOCAL_SAMPLE_CALCULATOR, localSampleCalculator);
685688
MLEngineClassLoader.register(FunctionName.AGENT, agentExecutor);
@@ -689,7 +692,7 @@ public Collection<Object> createComponents(
689692

690693
MetricsCorrelation metricsCorrelation = new MetricsCorrelation(client, settings, clusterService);
691694
MLEngineClassLoader.register(FunctionName.METRICS_CORRELATION, metricsCorrelation);
692-
MLSearchHandler mlSearchHandler = new MLSearchHandler(client, xContentRegistry, modelAccessControlHelper, clusterService);
695+
MLSearchHandler mlSearchHandler = new MLSearchHandler(client, xContentRegistry, modelAccessControlHelper, clusterService, mlFeatureEnabledSetting);
693696
MLModelAutoReDeployer mlModelAutoRedeployer = new MLModelAutoReDeployer(
694697
clusterService,
695698
client,

plugin/src/test/java/org/opensearch/ml/action/connector/ExecuteConnectorTransportActionTests.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.opensearch.ml.common.connector.Connector;
3232
import org.opensearch.ml.common.connector.ConnectorProtocols;
3333
import org.opensearch.ml.common.connector.HttpConnector;
34+
import org.opensearch.ml.common.settings.MLFeatureEnabledSetting;
3435
import org.opensearch.ml.common.transport.MLTaskResponse;
3536
import org.opensearch.ml.common.transport.connector.MLExecuteConnectorRequest;
3637
import org.opensearch.ml.engine.encryptor.EncryptorImpl;
@@ -70,6 +71,8 @@ public class ExecuteConnectorTransportActionTests extends OpenSearchTestCase {
7071
@Mock
7172
private EncryptorImpl encryptor;
7273
@Mock
74+
private MLFeatureEnabledSetting mlFeatureEnabledSetting;
75+
@Mock
7376
private HttpConnector connector;
7477
@Mock
7578
private Task task;
@@ -109,7 +112,8 @@ public void setup() {
109112
scriptService,
110113
xContentRegistry,
111114
connectorAccessControlHelper,
112-
encryptor
115+
encryptor,
116+
mlFeatureEnabledSetting
113117
);
114118
}
115119

0 commit comments

Comments
 (0)