hadoop AbstractS3ATokenIdentifier 源码

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

haddop AbstractS3ATokenIdentifier 代码

文件路径:/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/delegation/AbstractS3ATokenIdentifier.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.s3a.auth.delegation;

import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.IOException;
import java.net.URI;
import java.util.Objects;
import java.util.UUID;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.delegation.web.DelegationTokenIdentifier;
import org.apache.hadoop.util.Time;

import static java.util.Objects.requireNonNull;

/**
 * An S3A Delegation Token Identifier: contains the information needed
 * to talk to S3A.
 *
 * These are loaded via the service loader API an used in a map of
 * Kind to class, which is then looked up to deserialize token
 * identifiers of a given class.
 *
 * Every non-abstract class must provide
 * <ol>
 *   <li>Their unique token kind.</li>
 *   <li>An empty constructor.</li>
 *   <li>An entry in the resource file
 *   {@code /META-INF/services/org.apache.hadoop.security.token.TokenIdentifier}
 *   </li>
 * </ol>
 *
 * The base implementation contains
 * <ol>
 *   <li>The URI of the FS.</li>
 *   <li>Encryption secrets for use in the destination FS.</li>
 * </ol>
 * Subclasses are required to add whatever information is needed to authenticate
 * the user with the credential provider which their binding class will
 * provide.
 *
 * <i>Important: Add no references to any AWS SDK class, to
 * ensure it can be safely deserialized whenever the relevant token
 * identifier of a token type declared in this JAR is examined.</i>
 */
public abstract class AbstractS3ATokenIdentifier
    extends DelegationTokenIdentifier {

  /**
   * The maximum string length supported for text fields.
   */
  protected static final int MAX_TEXT_LENGTH = 8192;

  /** Canonical URI of the bucket. */
  private URI uri;

  /**
   * Encryption secrets to also marshall with any credentials.
   * Set during creation to ensure it is never null.
   */
  private EncryptionSecrets encryptionSecrets = new EncryptionSecrets();

  /**
   * Timestamp of creation.
   * This is set to the current time; it will be overridden when
   * deserializing data.
   */
  private long created = System.currentTimeMillis();

  /**
   * An origin string for diagnostics.
   */
  private String origin = "";

  /**
   * This marshalled UUID can be used in testing to verify transmission,
   * and reuse; as it is printed you can see what is happending too.
   */
  private String uuid = UUID.randomUUID().toString();

  /**
   * Constructor.
   * @param kind token kind.
   * @param uri filesystem URI.
   * @param owner token owner.
   * @param renewer token renewer.
   * @param origin origin text for diagnostics.
   * @param encryptionSecrets encryption secrets to set.
   */
  protected AbstractS3ATokenIdentifier(
      final Text kind,
      final URI uri,
      final Text owner,
      final Text renewer,
      final String origin,
      final EncryptionSecrets encryptionSecrets) {
    this(kind,
         owner,
         (renewer != null ? renewer : new Text()),
         new Text(),
         uri);
    this.origin = requireNonNull(origin);
    this.encryptionSecrets = requireNonNull(encryptionSecrets);
  }

  /**
   * Constructor.
   * @param kind token kind.
   * @param owner token owner
   * @param renewer token renewer
   * @param realUser token real user
   * @param uri filesystem URI.
   */
  protected AbstractS3ATokenIdentifier(
      final Text kind,
      final Text owner,
      final Text renewer,
      final Text realUser,
      final URI uri) {
    super(kind, owner, renewer, realUser);
    this.uri = requireNonNull(uri);
    initializeIssueDate();
  }

  /**
   * Build from a token.
   * This has been written for refresh operations;
   * if someone implements refresh it will be relevant.
   * @param kind token kind.
   * @param token to to build from
   * @throws IOException failure to build the identifier.
   */
  protected AbstractS3ATokenIdentifier(
      final Text kind,
      final Token<AbstractS3ATokenIdentifier> token) throws IOException {
    super(kind);
    ByteArrayInputStream bais = new ByteArrayInputStream(token.getIdentifier());
    readFields(new DataInputStream(bais));
  }

  /**
   * For subclasses to use in their own empty-constructors.
   * @param kind token kind.
   */
  protected AbstractS3ATokenIdentifier(final Text kind) {
    super(kind);
    initializeIssueDate();
  }

  private void initializeIssueDate() {
    setIssueDate(Time.now());
  }

  public String getBucket() {
    return uri.getHost();
  }

  public URI getUri() {
    return uri;
  }

  public String getOrigin() {
    return origin;
  }

  public void setOrigin(final String origin) {
    this.origin = origin;
  }

  public long getCreated() {
    return created;
  }

  /**
   * Write state.
   * {@link org.apache.hadoop.io.Writable#write(DataOutput)}.
   * @param out destination
   * @throws IOException failure
   */
  @Override
  public void write(final DataOutput out) throws IOException {
    super.write(out);
    Text.writeString(out, uri.toString());
    Text.writeString(out, origin);
    Text.writeString(out, uuid);
    encryptionSecrets.write(out);
    out.writeLong(created);
  }

  /**
   * Read state.
   * {@link org.apache.hadoop.io.Writable#readFields(DataInput)}.
   *
   * Note: this operation gets called in toString() operations on tokens, so
   * must either always succeed, or throw an IOException to trigger the
   * catch and downgrade. RuntimeExceptions (e.g. Preconditions checks) are
   * not to be used here for this reason.)
   *
   * @param in input stream
   * @throws DelegationTokenIOException if the token binding is wrong.
   * @throws IOException IO problems.
   */
  @Override
  public void readFields(final DataInput in)
      throws DelegationTokenIOException, IOException {
    super.readFields(in);
    uri = URI.create(Text.readString(in, MAX_TEXT_LENGTH));
    origin = Text.readString(in, MAX_TEXT_LENGTH);
    uuid = Text.readString(in, MAX_TEXT_LENGTH);
    encryptionSecrets.readFields(in);
    created = in.readLong();
  }

  /**
   * Validate the token by looking at its fields.
   * @throws IOException on failure.
   */
  public void validate() throws IOException {
    if (uri == null) {
      throw new DelegationTokenIOException("No URI in " + this);
    }
  }

  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder(
        "S3ATokenIdentifier{");
    sb.append(getKind());
    sb.append("; uri=").append(uri);
    sb.append("; timestamp=").append(created);
    sb.append("; renewer=").append(getRenewer());
    sb.append("; encryption=").append(encryptionSecrets.toString());
    sb.append("; ").append(uuid);
    sb.append("; ").append(origin);
    sb.append('}');
    return sb.toString();
  }

  /**
   * Equality check is on superclass and UUID only.
   * @param o other.
   * @return true if the base class considers them equal and the URIs match.
   */
  @Override
  public boolean equals(final Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    if (!super.equals(o)) {
      return false;
    }
    final AbstractS3ATokenIdentifier that = (AbstractS3ATokenIdentifier) o;
    return Objects.equals(uuid, that.uuid) &&
        Objects.equals(uri, that.uri);
  }

  @Override
  public int hashCode() {
    return Objects.hash(super.hashCode(), uri);
  }

  /**
   * Return the expiry time in seconds since 1970-01-01.
   * @return the time when the session credential expire.
   */
  public long getExpiryTime() {
    return 0;
  }

  /**
   * Get the UUID of this token identifier.
   * @return a UUID.
   */
  public String getUuid() {
    return uuid;
  }

  /**
   * Get the encryption secrets.
   * @return the encryption secrets within this identifier.
   */
  public EncryptionSecrets getEncryptionSecrets() {
    return encryptionSecrets;
  }

  /**
   * Create the default origin text message with local hostname and
   * timestamp.
   * @return a string for token diagnostics.
   */
  public static String createDefaultOriginMessage() {
    return String.format("Created on %s at time %s.",
        NetUtils.getHostname(),
        java.time.Instant.now());
  }
}

相关信息

hadoop 源码目录

相关文章

hadoop AWSPolicyProvider 源码

hadoop AbstractDTService 源码

hadoop AbstractDelegationTokenBinding 源码

hadoop DelegationConstants 源码

hadoop DelegationOperations 源码

hadoop DelegationTokenIOException 源码

hadoop DelegationTokenProvider 源码

hadoop EncryptionSecretOperations 源码

hadoop EncryptionSecrets 源码

hadoop FullCredentialsTokenBinding 源码

0  赞