>From Hussain Towaileb <[email protected]>: Hussain Towaileb has submitted this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20517?usp=email )
Change subject: [ASTERIXDB-3662][EXT]: Add external stats tracker ...................................................................... [ASTERIXDB-3662][EXT]: Add external stats tracker Details: - External statss tracker can be used to collect different statistics about external data operations. Ext-ref: MB-68345 Change-Id: Ifca24a07d733f5652030032784676c0b3aea47f8 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20517 Reviewed-by: Murtadha Hubail <[email protected]> Reviewed-by: Hussain Towaileb <[email protected]> Tested-by: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> --- M asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java A asterixdb/asterix-app/src/main/java/org/apache/asterix/app/external/ExternalStatsTracker.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java M asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IApplicationContext.java D asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalCredentialsCache.java R asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalStatsTracker.java M asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/aws/AwsUtils.java 8 files changed, 135 insertions(+), 81 deletions(-) Approvals: Hussain Towaileb: Looks good to me, but someone else must approve Jenkins: Verified; Verified Murtadha Hubail: Looks good to me, approved diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java index 6ea7aeb..0126b6e 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java @@ -24,6 +24,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Supplier; +import org.apache.asterix.app.external.ExternalStatsTracker; import org.apache.asterix.app.result.ResultReader; import org.apache.asterix.common.api.IConfigValidator; import org.apache.asterix.common.api.IConfigValidatorFactory; @@ -55,6 +56,7 @@ import org.apache.asterix.common.dataflow.ICcApplicationContext; import org.apache.asterix.common.dataflow.IDataPartitioningProvider; import org.apache.asterix.common.external.IAdapterFactoryService; +import org.apache.asterix.common.external.IExternalStatsTracker; import org.apache.asterix.common.metadata.IMetadataBootstrap; import org.apache.asterix.common.metadata.IMetadataLockUtil; import org.apache.asterix.common.replication.INcLifecycleCoordinator; @@ -89,31 +91,31 @@ */ public class CcApplicationContext implements ICcApplicationContext { - private ICCServiceContext ccServiceCtx; - private IStorageComponentProvider storageComponentProvider; - private IGlobalRecoveryManager globalRecoveryManager; - private IResourceIdManager resourceIdManager; - private CompilerProperties compilerProperties; - private ExternalProperties externalProperties; - private MetadataProperties metadataProperties; - private StorageProperties storageProperties; - private TransactionProperties txnProperties; - private ActiveProperties activeProperties; - private BuildProperties buildProperties; - private ReplicationProperties replicationProperties; - private ExtensionProperties extensionProperties; - private MessagingProperties messagingProperties; - private NodeProperties nodeProperties; + private final ICCServiceContext ccServiceCtx; + private final IStorageComponentProvider storageComponentProvider; + private final IGlobalRecoveryManager globalRecoveryManager; + private final IResourceIdManager resourceIdManager; + private final CompilerProperties compilerProperties; + private final ExternalProperties externalProperties; + private final MetadataProperties metadataProperties; + private final StorageProperties storageProperties; + private final TransactionProperties txnProperties; + private final ActiveProperties activeProperties; + private final BuildProperties buildProperties; + private final ReplicationProperties replicationProperties; + private final ExtensionProperties extensionProperties; + private final MessagingProperties messagingProperties; + private final NodeProperties nodeProperties; private final CloudProperties cloudProperties; - private Supplier<IMetadataBootstrap> metadataBootstrapSupplier; + private final Supplier<IMetadataBootstrap> metadataBootstrapSupplier; private volatile HyracksConnection hcc; private volatile ResultSet resultSet; - private Object extensionManager; - private INcLifecycleCoordinator ftStrategy; - private IJobLifecycleListener activeLifeCycleListener; - private IMetadataLockManager mdLockManager; - private IMetadataLockUtil mdLockUtil; - private IClusterStateManager clusterStateManager; + private final Object extensionManager; + private final INcLifecycleCoordinator ftStrategy; + private final IJobLifecycleListener activeLifeCycleListener; + private final IMetadataLockManager mdLockManager; + private final IMetadataLockUtil mdLockUtil; + private final IClusterStateManager clusterStateManager; private final INodeJobTracker nodeJobTracker; private final ITxnIdFactory txnIdFactory; private final ICompressionManager compressionManager; @@ -127,6 +129,7 @@ private final IOManager ioManager; private final INamespacePathResolver namespacePathResolver; private final INamespaceResolver namespaceResolver; + private final IExternalStatsTracker externalStatsTracker; public CcApplicationContext(ICCServiceContext ccServiceCtx, HyracksConnection hcc, Supplier<IMetadataBootstrap> metadataBootstrapSupplier, IGlobalRecoveryManager globalRecoveryManager, @@ -177,6 +180,7 @@ this.globalTxManager = globalTxManager; this.ioManager = ioManager; dataPartitioningProvider = DataPartitioningProvider.create(this); + externalStatsTracker = new ExternalStatsTracker(); } @Override @@ -415,4 +419,9 @@ public IOManager getIoManager() { return ioManager; } + + @Override + public IExternalStatsTracker getExternalStatsTracker() { + return externalStatsTracker; + } } diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/external/ExternalStatsTracker.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/external/ExternalStatsTracker.java new file mode 100644 index 0000000..ec88b8f --- /dev/null +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/external/ExternalStatsTracker.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.asterix.app.external; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.asterix.common.external.IExternalStatsTracker; +import org.apache.asterix.external.util.ExternalDataConstants; + +public class ExternalStatsTracker implements IExternalStatsTracker { + + private final Map<String, Map<String, AtomicLong>> totalAwsAssumeRoleFailures; + + public ExternalStatsTracker() { + totalAwsAssumeRoleFailures = new ConcurrentHashMap<>(); + } + + @Override + public String resolveName(Map<String, String> configuration) { + // if dataset name is not in the configuration, it means we are still creating the dataset, return empty string + if (!configuration.containsKey(ExternalDataConstants.KEY_DATASET)) { + return ""; + } + + String database = configuration.get(ExternalDataConstants.KEY_DATASET_DATABASE); + String dataverse = configuration.get(ExternalDataConstants.KEY_DATASET_DATAVERSE); + String dataset = configuration.get(ExternalDataConstants.KEY_DATASET); + String name; + if (database != null && !database.isEmpty()) { + name = database + "." + dataverse + "." + dataset; + } else { + name = dataverse + "." + dataset; + } + return name; + } + + @Override + public void incrementAwsAssumeRoleFailure(String name, String roleArn) { + // empty name means we are creating the external collection still + if (name.isEmpty()) { + return; + } + Map<String, AtomicLong> map = + totalAwsAssumeRoleFailures.computeIfAbsent(name, key -> new ConcurrentHashMap<>()); + map.computeIfAbsent(roleArn, key -> new AtomicLong()).incrementAndGet(); + } +} diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java index f669d48..fa573a0 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java @@ -31,6 +31,7 @@ import java.util.concurrent.ExecutorService; import org.apache.asterix.active.ActiveManager; +import org.apache.asterix.app.external.ExternalStatsTracker; import org.apache.asterix.app.result.ResultReader; import org.apache.asterix.cloud.CloudConfigurator; import org.apache.asterix.cloud.LocalPartitionBootstrapper; @@ -62,8 +63,7 @@ import org.apache.asterix.common.context.DiskWriteRateLimiterProvider; import org.apache.asterix.common.context.GlobalVirtualBufferCache; import org.apache.asterix.common.context.IStorageComponentProvider; -import org.apache.asterix.common.external.IExternalCredentialsCache; -import org.apache.asterix.common.external.IExternalCredentialsCacheUpdater; +import org.apache.asterix.common.external.IExternalStatsTracker; import org.apache.asterix.common.library.ILibraryManager; import org.apache.asterix.common.replication.IReplicationChannel; import org.apache.asterix.common.replication.IReplicationManager; @@ -193,8 +193,7 @@ private final INamespacePathResolver namespacePathResolver; private final INamespaceResolver namespaceResolver; private IDiskCacheMonitoringService diskCacheService; - protected IExternalCredentialsCache externalCredentialsCache; - protected IExternalCredentialsCacheUpdater externalCredentialsCacheUpdater; + private final IExternalStatsTracker externalStatsTracker; public NCAppRuntimeContext(INCServiceContext ncServiceContext, NCExtensionManager extensionManager, IPropertiesFactory propertiesFactory, INamespaceResolver namespaceResolver, @@ -219,6 +218,7 @@ cacheManager = new CacheManager(); this.namespacePathResolver = namespacePathResolver; this.namespaceResolver = namespaceResolver; + externalStatsTracker = new ExternalStatsTracker(); } @Override @@ -770,6 +770,11 @@ return partitionBootstrapper; } + @Override + public IExternalStatsTracker getExternalStatsTracker() { + return externalStatsTracker; + } + private int getResourceIdBlockSize() { return isCloudDeployment() ? storageProperties.getStoragePartitionsCount() : ncServiceContext.getIoManager().getIODevices().size(); diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java index 731f411..b55d763 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java @@ -6046,7 +6046,6 @@ String adapter = externalDetails.getAdapter(); Map<String, String> details = new HashMap<>(properties); details.put(ExternalDataConstants.KEY_EXTERNAL_SOURCE_TYPE, adapter); - metadataProvider.setExternalEntityId(details); validateAdapterSpecificProperties(details, srcLoc, appCtx); } @@ -6057,7 +6056,6 @@ String adapterName = externalDetailsDecl.getAdapter(); Map<String, String> properties = externalDetailsDecl.getProperties(); properties.put(ExternalDataConstants.KEY_EXTERNAL_SOURCE_TYPE, adapterName); - md.setExternalEntityId(properties); WriterValidationUtil.validateWriterConfiguration(adapterName, supportedAdapters, properties, sourceLocation); return properties; } diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IApplicationContext.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IApplicationContext.java index eabebf7..3e9f719 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IApplicationContext.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/IApplicationContext.java @@ -29,6 +29,7 @@ import org.apache.asterix.common.config.ReplicationProperties; import org.apache.asterix.common.config.StorageProperties; import org.apache.asterix.common.config.TransactionProperties; +import org.apache.asterix.common.external.IExternalStatsTracker; import org.apache.hyracks.api.application.IServiceContext; import org.apache.hyracks.api.client.IHyracksClientConnection; import org.apache.hyracks.api.exceptions.HyracksDataException; @@ -106,4 +107,6 @@ INamespaceResolver getNamespaceResolver(); INamespacePathResolver getNamespacePathResolver(); + + IExternalStatsTracker getExternalStatsTracker(); } diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalCredentialsCache.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalCredentialsCache.java deleted file mode 100644 index 689ff16..0000000 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalCredentialsCache.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.asterix.common.external; - -public interface IExternalCredentialsCache { - - /** - * Returns the cached credentials. - * - * @param key credentials key - * @return credentials if present and not expired/need refreshing, null otherwise - */ - Object get(String key); - - /** - * Deletes the cache for the provided entity - * - * @param key credentials key - */ - void delete(String key); - - /** - * Updates the credentials cache with the provided credentials for the specified name - * - * @param key credentials key - * @param credentials credentials to cache - */ - void put(String key, Object credentials); -} diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalCredentialsCacheUpdater.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalStatsTracker.java similarity index 66% rename from asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalCredentialsCacheUpdater.java rename to asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalStatsTracker.java index 48553c0..40493cc 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalCredentialsCacheUpdater.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/external/IExternalStatsTracker.java @@ -20,16 +20,18 @@ import java.util.Map; -import org.apache.asterix.common.exceptions.CompilationException; -import org.apache.hyracks.api.exceptions.HyracksDataException; - -public interface IExternalCredentialsCacheUpdater { +public interface IExternalStatsTracker { /** - * Generates new credentials and caches them + * Resolves a name from the given configuration map * - * @param configuration configuration containing external collection details + * @param configuration The configuration map + * @return The resolved name */ - Object generateAndCacheCredentials(Map<String, String> configuration) - throws HyracksDataException, CompilationException; + String resolveName(Map<String, String> configuration); + + /** + * Increments the total AWS Assume Role failure count + */ + void incrementAwsAssumeRoleFailure(String name, String roleArn); } diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/aws/AwsUtils.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/aws/AwsUtils.java index 5ffd7e2..974eceb 100644 --- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/aws/AwsUtils.java +++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/aws/AwsUtils.java @@ -43,6 +43,7 @@ import org.apache.asterix.common.api.IApplicationContext; import org.apache.asterix.common.exceptions.CompilationException; import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.common.external.IExternalStatsTracker; import org.apache.hyracks.api.util.CleanupUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -187,6 +188,22 @@ // build sts client used for assuming role ClientOverrideConfiguration.Builder clientConfigurationBuilder = ClientOverrideConfiguration.builder(); clientConfigurationBuilder.addExecutionInterceptor(ASSUME_ROLE_INTERCEPTOR); + clientConfigurationBuilder.addExecutionInterceptor(new ExecutionInterceptor() { + @Override + public void onExecutionFailure(Context.FailedExecution context, ExecutionAttributes executionAttributes) { + SdkRequest req = context.request(); + if (req instanceof AssumeRoleRequest assumeReq) { + String roleArn = assumeReq.roleArn(); + Throwable th = context.exception(); + LOGGER.info("encountered issue assuming role ({}): {}", roleArn, getMessageOrToString(th)); + + IExternalStatsTracker externalStatsTracker = appCtx.getExternalStatsTracker(); + String name = externalStatsTracker.resolveName(configuration); + externalStatsTracker.incrementAwsAssumeRoleFailure(name, roleArn); + } + ExecutionInterceptor.super.onExecutionFailure(context, executionAttributes); + } + }); ClientOverrideConfiguration clientConfiguration = clientConfigurationBuilder.build(); StsClientBuilder stsClientBuilder = StsClient.builder(); -- To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20517?usp=email To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings?usp=email Gerrit-MessageType: merged Gerrit-Project: asterixdb Gerrit-Branch: phoenix Gerrit-Change-Id: Ifca24a07d733f5652030032784676c0b3aea47f8 Gerrit-Change-Number: 20517 Gerrit-PatchSet: 5 Gerrit-Owner: Hussain Towaileb <[email protected]> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Hussain Towaileb <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Murtadha Hubail <[email protected]>
