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

io.fabric8.kubernetes.client.utils.KubernetesVersionFactory Maven / Gradle / Ivy

/**
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed 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 io.fabric8.kubernetes.client.utils;

import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A factory that is creating a version instance for a given version string.
 * Returns {@link KubernetesVersion} instances for kubernetes versions (starts with 'v')
 * and {@link NonKubernetesVersion} otherwise.
 */
public class KubernetesVersionFactory {

    private KubernetesVersionFactory() {}

    public static Version create(String versionValue) {
        Version version = KubernetesVersion.FACTORY.create(versionValue);
        if (version == null) {
            version = NonKubernetesVersion.FACTORY.create(versionValue);
        }
        return version;
    }

    public interface VersionFactory {
        T create(String version);
    }

    /**
     * A kubernetes version. This represents a version that starts with a 'v' followed by a numerical major version.
     * Optionally this may be followed by an 'alpha' or 'beta' qualifier and an also optional numeric minor version.
     */
    public static class KubernetesVersion extends Version {

        public static final VersionFactory FACTORY = new VersionFactory() {

            private final Pattern versionPattern = Pattern.compile("v([0-9]+)((alpha|beta)([0-9]+)?)*");

            @Override
            public KubernetesVersion create(String version) {
                if (version == null) {
                    return null;
                }
                Matcher matcher = versionPattern.matcher(version);
                if (!matcher.matches()) {
                    return null;
                }
                Integer majorValue = getInt(matcher.group(1));
                String qualifierValue = matcher.group(3);
                Integer minorValue = getInt(matcher.group(4));
                return new KubernetesVersion(majorValue, qualifierValue, minorValue, version);
            }

            private Integer getInt(String value) {
                if (value == null) {
                    return null;
                }
                try {
                    return Integer.parseInt(value);
                } catch(NumberFormatException e) {
                    return null;
                }
            }
        };

        private final Integer major;
        private final Optional qualifier;
        private final Optional minor;

        private KubernetesVersion(Integer major, String qualifier, Integer minor, String version) {
            super(version);
            this.major = major;
            this.qualifier = Optional.ofNullable(qualifier);
            this.minor = Optional.ofNullable(minor);
        }

        public Integer getMajor() {
            return major;
        }

        public Optional getQualifier() {
            return qualifier;
        }

        public Optional getMinor() {
            return minor;
        }

        public boolean isStable() {
            return qualifier.orElse(null) == null;
        }

        @Override
        public boolean isKubernetes() {
            return true;
        }

        /**
         * Compares this version to another version and returns whether this version has a
         * higher, equal or lower priority than the version that it is being compared to.
         *
         * The kubernetes specs v1.17 at Version Priority
         * state the following:
         *
         * 
    *
  • Entries that follow Kubernetes version patterns are sorted before those that do not.
  • *
  • For entries that follow Kubernetes version patterns, the numeric portions of the version string is sorted largest to smallest.
  • *
  • If the strings beta or alpha follow the first numeric portion, they sorted in that order, after the equivalent string without the beta * or alpha suffix (which is presumed to be the GA version).
  • *
  • If another number follows the beta, or alpha, those numbers are also sorted from largest to smallest.
  • *
  • Strings that don’t fit the above format are sorted alphabetically and the numeric portions are not treated specially. Notice that in the example below, foo1 is sorted above foo10. * This is different from the sorting of the numeric portion of entries that do follow the Kubernetes version patterns.
  • *
* * @param other the version to compare this version to * @return -1 if this version has a lower, 1 if it has a higher or 0 if the priorities are equal * */ @Override public int compareTo(Version other) { if (other == this) { return 0; } if (other instanceof NonKubernetesVersion) { return 1; } if (!(other instanceof KubernetesVersion)) { return 1; } KubernetesVersion otherKube = (KubernetesVersion) other; if (qualifier.isPresent()) { if (!otherKube.qualifier.isPresent()) { return -1; } int qualifierComparison = qualifier.get().compareTo(otherKube.qualifier.orElse(null)); if (qualifierComparison != 0) { return qualifierComparison; } int majorComparison = compareMajor(otherKube); if (majorComparison != 0) { return majorComparison; } return compareMinor(otherKube); } else { if (!otherKube.qualifier.isPresent()) { return compareMajor(otherKube); } else { return 1; } } } private int compareMajor(KubernetesVersion other) { return major.compareTo(other.major); } private int compareMinor(KubernetesVersion other) { if (minor.isPresent()) { if (!other.minor.isPresent()) { return 1; } return minor.get().compareTo(other.minor.orElse(null)); } else { if (!other.minor.isPresent()) { return 0; } return -1; } } } /** * A non kubernetes version which is any version string that does not start with a 'v'. */ public static class NonKubernetesVersion extends Version { public static final VersionFactory FACTORY = version -> { if (version == null) { return null; } return new NonKubernetesVersion(version); }; private NonKubernetesVersion(String version) { super(version); } @Override public boolean isKubernetes() { return false; } /** * Non-Kubernetes versions have lower priority than kubernetes versions. Among them they're inverse-lexicographically sorted. * * @param other the other version to compare to * @return -1 if this has a lower, 0 if equal or 1 if higher priority */ @Override public int compareTo(Version other) { if (other == this) { return 0; } if (other instanceof KubernetesVersion) { return -1; } else if (other instanceof NonKubernetesVersion) { return full.compareTo(other.full) * -1; // inverse lexicographical order } else { return -1; } } } protected abstract static class Version implements Comparable { protected final String full; protected Version(String full) { this.full = full; } public abstract boolean isKubernetes(); public String getFull() { return full; } @Override public String toString() { return full; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy