All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.yarn.nodelabels.NodeLabelUtil Maven / Gradle / Ivy

The newest version!
/**
 * 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.yarn.nodelabels;

import com.google.common.base.Strings;
import org.apache.hadoop.yarn.api.records.NodeAttribute;
import org.apache.hadoop.yarn.api.records.NodeAttributeKey;

import java.io.IOException;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Utility class for all NodeLabel and NodeAttribute operations.
 */
public final class NodeLabelUtil {
  private NodeLabelUtil() {
  }

  private static final int MAX_LABEL_LENGTH = 255;
  private static final Pattern LABEL_OR_VALUE_PATTERN =
      Pattern.compile("^[0-9a-zA-Z][0-9a-zA-Z-_]*");
  private static final Pattern PREFIX_PATTERN =
      Pattern.compile("^[0-9a-zA-Z][0-9a-zA-Z-_\\.]*");
  private static final Pattern ATTRIBUTE_VALUE_PATTERN =
      Pattern.compile("^[0-9a-zA-Z][0-9a-zA-Z-_.]*");
  private static final Pattern ATTRIBUTE_NAME_PATTERN =
      Pattern.compile("^[0-9a-zA-Z][0-9a-zA-Z-_]*");

  public static void checkAndThrowLabelName(String label) throws IOException {
    if (label == null || label.isEmpty() || label.length() > MAX_LABEL_LENGTH) {
      throw new IOException("label added is empty or exceeds "
          + MAX_LABEL_LENGTH + " character(s)");
    }
    label = label.trim();

    boolean match = LABEL_OR_VALUE_PATTERN.matcher(label).matches();

    if (!match) {
      throw new IOException("label name should only contains "
          + "{0-9, a-z, A-Z, -, _} and should not started with {-,_}"
          + ", now it is= " + label);
    }
  }

  public static void checkAndThrowAttributeName(String attributeName)
      throws IOException {
    if (attributeName == null || attributeName.isEmpty()
        || attributeName.length() > MAX_LABEL_LENGTH) {
      throw new IOException(
          "attribute name added is empty or exceeds " + MAX_LABEL_LENGTH
              + " character(s)");
    }
    attributeName = attributeName.trim();

    boolean match = ATTRIBUTE_NAME_PATTERN.matcher(attributeName).matches();

    if (!match) {
      throw new IOException("attribute name should only contains "
          + "{0-9, a-z, A-Z, -, _} and should not started with {-,_}"
          + ", now it is= " + attributeName);
    }
  }

  public static void checkAndThrowAttributeValue(String value)
      throws IOException {
    if (value == null) {
      return;
    } else if (value.trim().length() > MAX_LABEL_LENGTH) {
      throw new IOException("Attribute value added exceeds " + MAX_LABEL_LENGTH
          + " character(s)");

    }
    value = value.trim();
    if(value.isEmpty()) {
      return;
    }

    boolean match = ATTRIBUTE_VALUE_PATTERN.matcher(value).matches();

    if (!match) {
      throw new IOException("attribute value should only contains "
          + "{0-9, a-z, A-Z, -, _} and should not started with {-,_}"
          + ", now it is= " + value);
    }
  }

  public static void checkAndThrowAttributePrefix(String prefix)
      throws IOException {
    if (prefix == null) {
      throw new IOException("Attribute prefix cannot be null.");
    }
    if (prefix.trim().length() > MAX_LABEL_LENGTH) {
      throw new IOException("Attribute value added exceeds " + MAX_LABEL_LENGTH
          + " character(s)");
    }
    prefix = prefix.trim();
    if(prefix.isEmpty()) {
      return;
    }

    boolean match = PREFIX_PATTERN.matcher(prefix).matches();

    if (!match) {
      throw new IOException("attribute value should only contains "
          + "{0-9, a-z, A-Z, -, _,.} and should not started with {-,_}"
          + ", now it is= " + prefix);
    }
  }

  /**
   * Validate if a given set of attributes are valid. Attributes could be
   * invalid if any of following conditions is met:
   *
   * 
    *
  • Missing prefix: the attribute doesn't have prefix defined
  • *
  • Malformed attribute prefix: the prefix is not in valid format
  • *
* @param attributeSet * @throws IOException */ public static void validateNodeAttributes(Set attributeSet) throws IOException { if (attributeSet != null && !attributeSet.isEmpty()) { for (NodeAttribute nodeAttribute : attributeSet) { NodeAttributeKey attributeKey = nodeAttribute.getAttributeKey(); if (attributeKey == null) { throw new IOException("AttributeKey must be set"); } String prefix = attributeKey.getAttributePrefix(); if (Strings.isNullOrEmpty(prefix)) { throw new IOException("Attribute prefix must be set"); } // Verify attribute prefix format. checkAndThrowAttributePrefix(prefix); // Verify attribute name format. checkAndThrowAttributeName(attributeKey.getAttributeName()); // Verify attribute value format. checkAndThrowAttributeValue(nodeAttribute.getAttributeValue()); } } } /** * Filter a set of node attributes by a given prefix. Returns a filtered * set of node attributes whose prefix equals the given prefix. * If the prefix is null or empty, then the original set is returned. * @param attributeSet node attribute set * @param prefix node attribute prefix * @return a filtered set of node attributes */ public static Set filterAttributesByPrefix( Set attributeSet, String prefix) { if (Strings.isNullOrEmpty(prefix)) { return attributeSet; } return attributeSet.stream() .filter(nodeAttribute -> prefix .equals(nodeAttribute.getAttributeKey().getAttributePrefix())) .collect(Collectors.toSet()); } /** * Are these two input node attributes the same. * @return true if they are the same */ public static boolean isNodeAttributesEquals( Set leftNodeAttributes, Set rightNodeAttributes) { if (leftNodeAttributes == null && rightNodeAttributes == null) { return true; } else if (leftNodeAttributes == null || rightNodeAttributes == null || leftNodeAttributes.size() != rightNodeAttributes.size()) { return false; } return leftNodeAttributes.stream() .allMatch(e -> isNodeAttributeIncludes(rightNodeAttributes, e)); } private static boolean isNodeAttributeIncludes( Set nodeAttributes, NodeAttribute checkNodeAttribute) { return nodeAttributes.stream().anyMatch( e -> e.equals(checkNodeAttribute) && Objects .equals(e.getAttributeValue(), checkNodeAttribute.getAttributeValue())); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy