| /* |
| * 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.geode.test.version; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Optional; |
| import java.util.Properties; |
| import java.util.function.BiConsumer; |
| |
| import org.apache.commons.lang3.JavaVersion; |
| import org.apache.commons.lang3.SystemUtils; |
| |
| /** |
| * VersionManager loads the class-paths for all of the releases of Geode configured for |
| * backward-compatibility testing in the geode-core build.gradle file. |
| * <p> |
| * Tests may use these versions in launching VMs to run older clients or servers. |
| * |
| * see Host.getVM(String, int) |
| */ |
| public class VersionManager { |
| public static final String CURRENT_VERSION = "000"; |
| public static final String GEODE_110 = "110"; |
| public static final String GEODE_120 = "120"; |
| public static final String GEODE_130 = "130"; |
| public static final String GEODE_140 = "140"; |
| |
| private static VersionManager instance; |
| |
| protected String loadFailure = ""; |
| |
| protected static void init() { |
| instance = new VersionManager(); |
| final String fileName = "geodeOldVersionClasspaths.txt"; |
| final String installLocations = "geodeOldVersionInstalls.txt"; |
| instance.findVersions(fileName); |
| instance.findInstalls(installLocations); |
| // System.out |
| // .println("VersionManager has loaded the following classpaths:\n" + instance.classPaths); |
| } |
| |
| public static VersionManager getInstance() { |
| if (instance == null) { |
| init(); |
| } |
| return instance; |
| } |
| |
| /** |
| * for unit testing, this creates a VersionManager with paths loaded from the given file, which |
| * may or may not exist. The instance is not retained |
| */ |
| protected static VersionManager getInstance(String classpathsFileName, String installFileName) { |
| VersionManager result = new VersionManager(); |
| result.findVersions(classpathsFileName); |
| return result; |
| } |
| |
| /** |
| * classPaths for old versions loaded from a file generated by Gradle |
| */ |
| private Map<String, String> classPaths = new HashMap<>(); |
| |
| private List<String> testVersions = new ArrayList<String>(10); |
| |
| private Map<String, String> installs = new HashMap(); |
| |
| /** |
| * Test to see if a version string is known to VersionManager. Versions are either CURRENT_VERSION |
| * or one of the versions returned by VersionManager#getVersions() |
| */ |
| public boolean isValidVersion(String version) { |
| return version.equals(CURRENT_VERSION) || classPaths.containsKey(version); |
| } |
| |
| /** |
| * Returns true if the version is equal to the CURRENT_VERSION constant |
| */ |
| public static boolean isCurrentVersion(String version) { |
| return version.equals(CURRENT_VERSION); |
| } |
| |
| /** |
| * Returns the classPath for the given version, or null if the version is not valid. Use |
| * CURRENT_VERSION for the version in development. |
| */ |
| public String getClasspath(String version) { |
| return classPaths.get(version); |
| } |
| |
| |
| public String getInstall(String version) { |
| return installs.get(version); |
| } |
| |
| /** |
| * Returns a list of older versions available for testing |
| */ |
| public List<String> getVersions() { |
| checkForLoadFailure(); |
| return Collections.unmodifiableList(testVersions); |
| } |
| |
| public List<String> getVersionsWithoutCurrent() { |
| checkForLoadFailure(); |
| List<String> result = new ArrayList<>(testVersions); |
| result.remove(CURRENT_VERSION); |
| return result; |
| } |
| |
| |
| private void checkForLoadFailure() { |
| if (loadFailure.length() > 0) { |
| throw new InternalError(loadFailure); |
| } |
| } |
| |
| private void findVersions(String fileName) { |
| // this file is created by the gradle task createClasspathsPropertiesFile |
| readVersionsFile(fileName, (version, path) -> { |
| Optional<String> parsedVersion = parseVersion(version); |
| if (parsedVersion.isPresent()) { |
| if (parsedVersion.get().equals("140") |
| && SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9)) { |
| // Serialization filtering was added in 140, but the support for them in java 9+ was added |
| // in 150. As a result, 140 servers and clients will fail categorically when run in |
| // Java 9+ even with the additional libs (jaxb and activation) in the classpath |
| System.err.println( |
| "Geode version 140 is incompatible with Java 9 and higher. Skipping this version."); |
| } else { |
| classPaths.put(parsedVersion.get(), path); |
| testVersions.add(parsedVersion.get()); |
| } |
| } |
| }); |
| Collections.sort(testVersions); |
| } |
| |
| private void findInstalls(String fileName) { |
| readVersionsFile(fileName, (version, install) -> { |
| Optional<String> parsedVersion = parseVersion(version); |
| if (parsedVersion.isPresent()) { |
| installs.put(parsedVersion.get(), install); |
| } |
| }); |
| } |
| |
| private Optional<String> parseVersion(String version) { |
| String parsedVersion = null; |
| if (version.startsWith("test") && version.length() >= "test".length()) { |
| if (version.equals("test")) { |
| parsedVersion = CURRENT_VERSION; |
| } else { |
| parsedVersion = version.substring("test".length()); |
| } |
| } |
| return Optional.ofNullable(parsedVersion); |
| } |
| |
| private void readVersionsFile(String fileName, BiConsumer<String, String> consumer) { |
| Properties props = readPropertiesFile(fileName); |
| props.forEach((k, v) -> { |
| consumer.accept(k.toString(), v.toString()); |
| }); |
| } |
| |
| public Properties readPropertiesFile(String fileName) { |
| // this file is created by the gradle task createClasspathsPropertiesFile |
| Properties props = new Properties(); |
| URL url = VersionManager.class.getResource("/" + fileName); |
| if (url == null) { |
| loadFailure = "VersionManager: unable to locate " + fileName + " in class-path"; |
| return props; |
| } |
| try (InputStream in = VersionManager.class.getResource("/" + fileName).openStream()) { |
| props.load(in); |
| } catch (IOException e) { |
| loadFailure = "VersionManager: unable to read resource " + fileName; |
| return props; |
| } |
| return props; |
| } |
| } |