hadoop LocalSASKeyGeneratorImpl 源码

  • 2022-10-20
  • 浏览 (174)

haddop LocalSASKeyGeneratorImpl 代码

文件路径:/hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azure/LocalSASKeyGeneratorImpl.java

/**
 * 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.hadoop.fs.azure;

import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TimeZone;

import org.apache.hadoop.conf.Configuration;

import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.SharedAccessAccountPermissions;
import com.microsoft.azure.storage.SharedAccessAccountPolicy;
import com.microsoft.azure.storage.SharedAccessAccountResourceType;
import com.microsoft.azure.storage.SharedAccessAccountService;
import com.microsoft.azure.storage.StorageCredentialsAccountAndKey;
import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/***
 * Local SAS Key Generation implementation. This class resides in
 * the same address space as the WASB driver.
 *
 * This class gets typically used for testing purposes.
 *
 */

public class LocalSASKeyGeneratorImpl extends SASKeyGeneratorImpl {

  public static final Logger LOG = LoggerFactory.getLogger(
      LocalSASKeyGeneratorImpl.class);

  /**
   * Map to cache CloudStorageAccount instances.
   */
  private Map<String, CloudStorageAccount> storageAccountMap;
  private CachingAuthorizer<CachedSASKeyEntry, URI> cache;
  private static final int HOURS_IN_DAY = 24;

  public LocalSASKeyGeneratorImpl(Configuration conf) {
    super(conf);
    storageAccountMap = new HashMap<String, CloudStorageAccount>();
    cache = new CachingAuthorizer<>(getSasKeyExpiryPeriod(), "SASKEY");
    cache.init(conf);
  }

  /**
   * Implementation to generate SAS Key for a container
   */
  @Override
  public URI getContainerSASUri(String accountName, String container)
      throws SASKeyGenerationException {

    LOG.debug("Retrieving Container SAS URI For {}@{}", container, accountName);
    try {

      CachedSASKeyEntry cacheKey = new CachedSASKeyEntry(accountName, container, "/");
      URI cacheResult = cache.get(cacheKey);
      if (cacheResult != null) {
        return cacheResult;
      }

      CloudStorageAccount account =
          getSASKeyBasedStorageAccountInstance(accountName);
      CloudBlobClient client = account.createCloudBlobClient();
      URI sasKey = client.getCredentials().transformUri(
          client.getContainerReference(container).getUri());
      cache.put(cacheKey, sasKey);
      return sasKey;

    } catch (StorageException stoEx) {
      throw new SASKeyGenerationException("Encountered StorageException while"
          + " generating SAS Key for container " + container + " inside "
              + "storage account " + accountName, stoEx);
    } catch (URISyntaxException uriSyntaxEx) {
      throw new SASKeyGenerationException("Encountered URISyntaxException while"
          + " generating SAS Key for container " + container + " inside storage"
              + " account " + accountName, uriSyntaxEx);
    }
  }

  /**
   * Helper method that creates a CloudStorageAccount instance based on
   *  SAS key for accountName
   *
   * @param accountName Storage Account Name
   * @return CloudStorageAccount instance created using SAS key for
   *   the Storage Account.
   * @throws SASKeyGenerationException
   */
  private CloudStorageAccount getSASKeyBasedStorageAccountInstance(
      String accountName) throws SASKeyGenerationException {
    LOG.debug("Creating SAS key from account instance {}", accountName);
    try {

      String accountNameWithoutDomain =
          getAccountNameWithoutDomain(accountName);

      CloudStorageAccount account =
          getStorageAccountInstance(accountNameWithoutDomain,
              AzureNativeFileSystemStore.getAccountKeyFromConfiguration(
                  accountName, getConf()));

      return new CloudStorageAccount(
          new StorageCredentialsSharedAccessSignature(
              account.generateSharedAccessSignature(
                  getDefaultAccountAccessPolicy())), false,
                  account.getEndpointSuffix(), accountNameWithoutDomain);

    } catch (KeyProviderException keyProviderEx) {
      throw new SASKeyGenerationException("Encountered KeyProviderException"
          + " while retrieving Storage key from configuration for account "
          + accountName, keyProviderEx);
    } catch (InvalidKeyException invalidKeyEx) {
      throw new SASKeyGenerationException("Encoutered InvalidKeyException "
          + "while generating Account level SAS key for account" + accountName,
          invalidKeyEx);
    } catch(StorageException storeEx) {
      throw new SASKeyGenerationException("Encoutered StorageException while "
          + "generating Account level SAS key for account" + accountName,
            storeEx);
    } catch(URISyntaxException uriSyntaxEx) {
      throw new SASKeyGenerationException("Encountered URISyntaxException for"
          + " account " + accountName, uriSyntaxEx);
    }
  }

  /**
   * Implementation for generation of Relative Path Blob SAS Uri.
   */
  @Override
  public URI getRelativeBlobSASUri(String accountName, String container,
      String relativePath) throws SASKeyGenerationException {

    CloudBlobContainer sc = null;
    CloudBlobClient client = null;
    CachedSASKeyEntry cacheKey = null;

    try {

      cacheKey = new CachedSASKeyEntry(accountName, container, relativePath);
      URI cacheResult = cache.get(cacheKey);
      if (cacheResult != null) {
        return cacheResult;
      }

      CloudStorageAccount account =
          getSASKeyBasedStorageAccountInstance(accountName);
      client = account.createCloudBlobClient();
      sc = client.getContainerReference(container);
    } catch (URISyntaxException uriSyntaxEx) {
      throw new SASKeyGenerationException("Encountered URISyntaxException "
          + "while getting container references for container " + container
          + " inside storage account : " + accountName, uriSyntaxEx);
    } catch (StorageException stoEx) {
      throw new SASKeyGenerationException("Encountered StorageException while "
          + "getting  container references for container " + container
          + " inside storage account : " + accountName, stoEx);
    }

    CloudBlockBlob blob = null;
    try {
      blob = sc.getBlockBlobReference(relativePath);
    } catch (URISyntaxException uriSyntaxEx) {
      throw new SASKeyGenerationException("Encountered URISyntaxException while "
          + "getting Block Blob references for container " + container
          + " inside storage account : " + accountName, uriSyntaxEx);
    } catch (StorageException stoEx) {
      throw new SASKeyGenerationException("Encountered StorageException while "
          + "getting Block Blob references for container " + container
          + " inside storage account : " + accountName, stoEx);
    }

    try {
      URI sasKey = client.getCredentials().transformUri(blob.getUri());
      cache.put(cacheKey, sasKey);
      return sasKey;
    } catch (StorageException stoEx) {
      throw new SASKeyGenerationException("Encountered StorageException while "
          + "generating SAS key for Blob: " + relativePath + " inside "
          + "container : " + container + " in Storage Account : " + accountName,
              stoEx);
    } catch (URISyntaxException uriSyntaxEx) {
      throw new SASKeyGenerationException("Encountered URISyntaxException "
          + "while generating SAS key for Blob: " + relativePath + " inside "
          + "container: " + container + " in Storage Account : " + accountName,
              uriSyntaxEx);
    }
  }

  /**
   * Helper method that creates CloudStorageAccount Instance using the
   * storage account key.
   * @param accountName Name of the storage account
   * @param accountKey Storage Account key
   * @return CloudStorageAccount instance for the storage account.
   * @throws SASKeyGenerationException
   */
  private CloudStorageAccount getStorageAccountInstance(String accountName,
      String accountKey) throws SASKeyGenerationException {

    if (!storageAccountMap.containsKey(accountName)) {
      if (accountKey == null || accountKey.isEmpty()) {
        throw new SASKeyGenerationException(
            "No key for Storage account " + accountName);
      }

      CloudStorageAccount account = null;
      try {
        account =
            new CloudStorageAccount(new StorageCredentialsAccountAndKey(
                accountName, accountKey));
      } catch (URISyntaxException uriSyntaxEx) {
        throw new SASKeyGenerationException("Encountered URISyntaxException "
            + "for account " + accountName, uriSyntaxEx);
      }

      storageAccountMap.put(accountName, account);
    }

    return storageAccountMap.get(accountName);
  }

  /**
   * Helper method that returns the Storage account name without
   * the domain name suffix.
   * @param fullAccountName Storage account name with domain name suffix
   * @return String
   */
  private String getAccountNameWithoutDomain(String fullAccountName) {
    StringTokenizer tokenizer = new StringTokenizer(fullAccountName, ".");
    return tokenizer.nextToken();
  }

  /**
   * Helper method to generate Access Policy for the Storage Account SAS Key
   * @return SharedAccessAccountPolicy
   */
  private SharedAccessAccountPolicy getDefaultAccountAccessPolicy() {

    SharedAccessAccountPolicy ap =
        new SharedAccessAccountPolicy();

    Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
    cal.setTime(new Date());
    cal.add(Calendar.HOUR, (int) getSasKeyExpiryPeriod() * HOURS_IN_DAY);

    ap.setSharedAccessExpiryTime(cal.getTime());
    ap.setPermissions(getDefaultAccoutSASKeyPermissions());
    ap.setResourceTypes(EnumSet.of(SharedAccessAccountResourceType.CONTAINER,
        SharedAccessAccountResourceType.OBJECT));
    ap.setServices(EnumSet.of(SharedAccessAccountService.BLOB));

    return ap;
  }

  private EnumSet<SharedAccessAccountPermissions> getDefaultAccoutSASKeyPermissions() {
    return EnumSet.of(SharedAccessAccountPermissions.ADD,
        SharedAccessAccountPermissions.CREATE,
        SharedAccessAccountPermissions.DELETE,
        SharedAccessAccountPermissions.LIST,
        SharedAccessAccountPermissions.READ,
        SharedAccessAccountPermissions.UPDATE,
        SharedAccessAccountPermissions.WRITE);
  }
}

相关信息

hadoop 源码目录

相关文章

hadoop AzureException 源码

hadoop AzureFileSystemThreadPoolExecutor 源码

hadoop AzureFileSystemThreadTask 源码

hadoop AzureLinkedStack 源码

hadoop AzureNativeFileSystemStore 源码

hadoop BlobMaterialization 源码

hadoop BlobOperationDescriptor 源码

hadoop BlockBlobAppendStream 源码

hadoop BlockBlobInputStream 源码

hadoop CachingAuthorizer 源码

0  赞