diff --git a/.github/workflows/sonar-branch.yml b/.github/workflows/sonar-branch.yml index f8010dca4..b4cb18f2e 100644 --- a/.github/workflows/sonar-branch.yml +++ b/.github/workflows/sonar-branch.yml @@ -16,11 +16,11 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Setup JDK 11 - uses: actions/setup-java@v3 + - name: Setup JDK + uses: actions/setup-java@v4 with: distribution: 'adopt' - java-version: 11 + java-version: 17 - name: Build and Test run: | mvn -B clean package diff --git a/documentation/site/content/userguide/tools/create-aux-image.md b/documentation/site/content/userguide/tools/create-aux-image.md index a6fb7caed..abe6c8b29 100644 --- a/documentation/site/content/userguide/tools/create-aux-image.md +++ b/documentation/site/content/userguide/tools/create-aux-image.md @@ -32,6 +32,7 @@ Usage: imagetool createAuxImage [OPTIONS] | `--httpProxyUrl` | Proxy for the HTTP protocol. Example: `http://myproxy:80` or `http:user:passwd@myproxy:8080` | | | `--httpsProxyUrl` | Proxy for the HTTPS protocol. Example: `https://myproxy:80` or `https:user:passwd@myproxy:8080` | | | `--packageManager` | Override the default package manager for the base image's operating system. Supported values: `APK`, `APTGET`, `NONE`, `YUM`, `ZYPPER` | | +| `--platform` | Set the target platform to build. Supported values: `linux/amd64` or `linux/arm64`. | | | `--pull` | Always attempt to pull a newer version of base images during the build. | | | `--skipcleanup` | Do not delete the build context folder, intermediate images, and failed build containers. For debugging purposes. | | | `--target` | Select the target environment in which the created image will be used. Supported values: `Default` (Docker/Kubernetes), `OpenShift`. See [Additional information](#--target). | `Default` | diff --git a/documentation/site/content/userguide/tools/create-image.md b/documentation/site/content/userguide/tools/create-image.md index 307955c84..43ba340bb 100644 --- a/documentation/site/content/userguide/tools/create-image.md +++ b/documentation/site/content/userguide/tools/create-image.md @@ -40,6 +40,7 @@ Usage: imagetool create [OPTIONS] | `--passwordEnv` | Environment variable containing the Oracle Support password, see `--user`. | | | `--passwordFile` | Path to a file containing just the Oracle Support password, see `--user`. | | | `--patches` | Comma separated list of patch IDs. Example: `12345678,87654321` | | +| `--platform` | Set the target platform to build. Supported values: `linux/amd64` or `linux/arm64`. | | | `--pull` | Always attempt to pull a newer version of base images during the build. | | | `--recommendedPatches` | Find and apply the latest PatchSet Update and recommended patches. This takes precedence over `--latestPSU`. | | | `--resourceTemplates` | One or more files containing placeholders that need to be resolved by the Image Tool. See [Resource Template Files](#resource-template-files). | | diff --git a/documentation/site/content/userguide/tools/rebase-image.md b/documentation/site/content/userguide/tools/rebase-image.md index 417a93652..7b279ec58 100644 --- a/documentation/site/content/userguide/tools/rebase-image.md +++ b/documentation/site/content/userguide/tools/rebase-image.md @@ -39,6 +39,7 @@ Usage: imagetool rebase [OPTIONS] | `--passwordEnv` | Environment variable containing the Oracle Support password, see `--user`. | | | `--passwordFile` | Path to a file containing just the Oracle Support password, see `--user`. | | | `--patches` | Comma separated list of patch IDs. Example: `12345678,87654321` | | +| `--platform` | Set the target platform to build. Supported values: `linux/amd64` or `linux/arm64`. | | | `--pull` | Always attempt to pull a newer version of base images during the build. | | | `--recommendedPatches` | Find and apply the latest PatchSet Update and recommended patches. This takes precedence over `--latestPSU`. | | | `--skipcleanup` | Do not delete the build context folder, intermediate images, and failed build containers. For debugging purposes. | | diff --git a/documentation/site/content/userguide/tools/update-image.md b/documentation/site/content/userguide/tools/update-image.md index bfeabaa7e..4a6e66fd2 100644 --- a/documentation/site/content/userguide/tools/update-image.md +++ b/documentation/site/content/userguide/tools/update-image.md @@ -41,6 +41,7 @@ Update WebLogic Docker image with selected patches | `--passwordEnv` | Environment variable containing the Oracle Support password, see `--user`. | | | `--passwordFile` | Path to a file containing just the Oracle Support password, see `--user`. | | | `--patches` | Comma separated list of patch IDs. Example: `12345678,87654321` | | +| `--platform` | Set the target platform to build. Supported values: `linux/amd64` or `linux/arm64`. | | | `--pull` | Always attempt to pull a newer version of base images during the build. | | | `--recommendedPatches` | (DEPRECATED) Find and apply the latest PatchSet Update and recommended patches. This takes precedence over `--latestPSU`. See [Additional information](#--recommendedpatches). | | | `--resourceTemplates` | One or more files containing placeholders that need to be resolved by the Image Tool. See [Resource Template Files](#resource-template-files). | | diff --git a/imagetool/pom.xml b/imagetool/pom.xml index b3f509ce1..d41329d5e 100644 --- a/imagetool/pom.xml +++ b/imagetool/pom.xml @@ -13,7 +13,7 @@ <parent> <artifactId>imagetool-parent</artifactId> <groupId>com.oracle.weblogic.lifecycle.imagetool</groupId> - <version>1.12.2</version> + <version>1.13.0</version> <relativePath>../pom.xml</relativePath> </parent> diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/api/model/CachedFile.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/api/model/CachedFile.java index 03bd84b63..622a7f0b4 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/api/model/CachedFile.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/api/model/CachedFile.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2021, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.api.model; @@ -15,6 +15,7 @@ import com.oracle.weblogic.imagetool.installer.InstallerType; import com.oracle.weblogic.imagetool.logging.LoggingFacade; import com.oracle.weblogic.imagetool.logging.LoggingFactory; +import com.oracle.weblogic.imagetool.util.BuildPlatform; import com.oracle.weblogic.imagetool.util.Utils; /** @@ -24,23 +25,47 @@ public class CachedFile { private static final LoggingFacade logger = LoggingFactory.getLogger(CachedFile.class); - private String id; - private String version; + private final String id; + private final String version; + private final String architecture; /** * Represents a locally cached file. * - * @param id cache ID (like installer type or patchId) - * @param version version number for the patch or installer. + * @param id cache ID (like installer type or patchId) + * @param version version number for the patch or installer. + * @param architecture the system architecture that this file/installer is applicable */ - public CachedFile(String id, String version) { + public CachedFile(String id, String version, String architecture) { Objects.requireNonNull(id, "key for the cached file cannot be null"); - logger.entering(id, version); + logger.entering(id, version, architecture); this.id = id; this.version = version; + this.architecture = architecture; logger.exiting(); } + /** + * Represents a locally cached file. + * + * @param id cache ID (like installer type or patchId) + * @param version version number for the patch or installer. + */ + public CachedFile(String id, String version) { + this(id, version, null); + } + + /** + * Represents a locally cached file. + * + * @param id cache ID (like installer type) + * @param version version number for the patch or installer. + * @param architecture the system architecture that this file/installer is applicable + */ + public CachedFile(InstallerType id, String version, String architecture) { + this(id.toString(), version, architecture); + } + /** * Represents a locally cached file. * @@ -48,7 +73,7 @@ public CachedFile(String id, String version) { * @param version version number for the patch or installer. */ public CachedFile(InstallerType id, String version) { - this(id.toString(), version); + this(id.toString(), version, null); } public static boolean isFileOnDisk(String filePath) { @@ -62,11 +87,23 @@ public static boolean isFileOnDisk(String filePath) { * @return the key to use for this cache entry, like xxxx_yyyy. */ public String getKey() { + return getCacheKey(architecture); + } + + private String getCacheKey(String architecture) { if (id.contains(CacheStore.CACHE_KEY_SEPARATOR)) { return id; - } else { - return id + CacheStore.CACHE_KEY_SEPARATOR + getVersion(); } + + StringBuilder key = new StringBuilder(32); + key.append(id); + key.append(CacheStore.CACHE_KEY_SEPARATOR); + key.append(version); + if (architecture != null) { + key.append(CacheStore.CACHE_KEY_SEPARATOR); + key.append(architecture); + } + return key.toString(); } /** @@ -77,8 +114,22 @@ public String getVersion() { return version; } + /** + * Get the system architecture name for this cache entry/file. + * @return the system architecture name applicable fo this cached file. + */ + public String getArchitecture() { + return architecture; + } + /** * Get the path of the file stored locally in the cache. + * Searching the cache starts with the specified key. If the key is not found in the cache, + * one additional attempt is made to find an acceptable alternative. The second search is based on + * whether the user specified a platform/architecture. If the user specified an architecture, check the cache + * for an entry listing without the architecture in the key (generic architecture entry). If the user + * did not specify an architecture, check the cache for an entry listing using the local architecture + * in case the user added the cache entry with the architecture. * @param cacheStore the cache store to search * @return the Path of the file, if found * @throws IOException throws FileNotFoundException, if this cached file (key) could not be located in the cache @@ -88,6 +139,25 @@ public String resolve(CacheStore cacheStore) throws IOException { String key = getKey(); logger.entering(key); String filePath = cacheStore.getValueFromCache(key); + if (filePath == null) { + // The KEY for this CachedFile was not found in the local cache. + logger.fine("Unable to find cache entry for {0}", key); + String alternateKey; + if (getArchitecture() == null) { + // The user did not specify an architecture in the KEY and that key was not found in the cache. + // Try adding the local architecture to the key, and look for that entry. + alternateKey = getCacheKey(BuildPlatform.getPlatformName()); + logger.fine("Trying local architecture: {0}", alternateKey); + } else { + // The user specified an architecture in the KEY, but that key was not found. + // Try removing the architecture from the key, and look for that entry. + alternateKey = getCacheKey(null); + logger.fine("Trying no-arch/generic architecture: {0}", alternateKey); + } + // second attempt to find a reasonable cache entry + filePath = cacheStore.getValueFromCache(alternateKey); + } + if (!isFileOnDisk(filePath)) { throw new FileNotFoundException(Utils.getMessage("IMG-0011", key)); } @@ -103,7 +173,7 @@ public String resolve(CacheStore cacheStore) throws IOException { * @return the path of the file copied to the Docker build context directory */ public Path copyFile(CacheStore cacheStore, String buildContextDir) throws IOException { - logger.entering(); + logger.entering(id, version, architecture, buildContextDir); Path result; String sourceFile = resolve(cacheStore); logger.info("IMG-0043", sourceFile); diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java index 298baf1b7..a03eae7cd 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java @@ -1,11 +1,10 @@ -// Copyright (c) 2020, 2022, Oracle and/or its affiliates. +// Copyright (c) 2020, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.aru; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.xml.xpath.XPathExpressionException; @@ -22,11 +21,11 @@ * Metadata for a patch, as defined by ARU. * Simple bean for holding metadata obtained from ARU for a given patch ID and version. */ -public class AruPatch implements Comparable<AruPatch> { +public class AruPatch { private static final LoggingFacade logger = LoggingFactory.getLogger(AruPatch.class); private String patchId; - private Version version; + private String version; private String description; private String product; private String release; @@ -51,15 +50,11 @@ public AruPatch patchId(String value) { * @return The string value of the version found in ARU. */ public String version() { - if (version != null) { - return version.toString(); - } else { - return null; - } + return version; } public AruPatch version(String value) { - version = new Version(value); + version = value; return this; } @@ -294,27 +289,4 @@ private static AruPatch selectPatchOffline(List<AruPatch> patches, String provid public String toString() { return patchId + " - " + description; } - - @Override - public int compareTo(AruPatch obj) { - return version.compareTo(obj.version); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AruPatch aruPatch = (AruPatch) o; - return Objects.equals(patchId, aruPatch.patchId) && Objects.equals(version, aruPatch.version) - && Objects.equals(release, aruPatch.release); - } - - @Override - public int hashCode() { - return Objects.hash(patchId, version, release); - } } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java index e7aebdc80..519aac9e6 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2022, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.aru; @@ -167,7 +167,7 @@ public List<AruPatch> getRecommendedPatches(FmwInstallerType type, String versio for (AruProduct product : type.products()) { List<AruPatch> patches = getRecommendedPatches(product, version, userId, password); // temporary, until OHS stops using same release number and product ID for two different installs - if (type == FmwInstallerType.OHS) { + if (type == FmwInstallerType.OHS_DB19) { if (product == AruProduct.OHS) { patches = patches.stream().filter(p -> p.description().contains(" DB19C ")) .collect(Collectors.toList()); @@ -267,7 +267,7 @@ public PatchLists(List<InstalledPatch> installedPatches, List<AruPatch> candidat } /** - * Validate patches conflicts by passing a list of patches. + * Check for patch conflicts by passing a list of patches. * * @param installedPatches opatch lsinventory content (null if none is passed) * @param patches A list of patches number diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/Version.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/Version.java deleted file mode 100644 index dfec386af..000000000 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/Version.java +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2023, Oracle and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -package com.oracle.weblogic.imagetool.aru; - -import java.util.Arrays; - -public class Version implements Comparable<Version> { - private final int[] sequence; - private final String stringValue; - - /** - * Representation of the ARU version number used for Oracle products. - * Version must be one or more integers separated by a period, ".". - * @param value String to be parsed as the ARU version. - */ - public Version(String value) { - stringValue = value; - - if (value != null && !value.isEmpty()) { - // split version into a sequence tokens using the period separator - sequence = Arrays.stream(value.split("\\.")) - .mapToInt(Integer::parseInt) - .toArray(); - } else { - sequence = new int[1]; - } - } - - /** - * Return the sequence of version tokens padded to the minimum length with 0's. - * The sequence will NOT be truncated. - * @param minLength minimum number of version tokens in the array. - * @return sequence of version tokens - */ - public int[] getSequence(int minLength) { - if (sequence.length < minLength) { - return Arrays.copyOf(sequence, minLength); - } - return sequence; - } - - /** - * Compare this version number against the provided version, returning -1, 0, or 1 if - * this version is less than, equal to, or greater than the provided version, respectively. - * @param provided the object to be compared. - * @return -1, 0, or 1 if this version is less than, equal to, or greater than the provided version - */ - @Override - public int compareTo(Version provided) { - int match = 0; - int sequenceLength = Math.max(sequence.length, provided.sequence.length); - int[] mySequence = getSequence(sequenceLength); - int[] providedSequence = provided.getSequence(sequenceLength); - - for (int i = 0; i < sequenceLength; i++) { - if (mySequence[i] > providedSequence[i]) { - match = 1; - } else if (mySequence[i] < providedSequence[i]) { - match = -1; - } - if (match != 0) { - break; - } - } - - return match; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Version version = (Version) o; - return this.compareTo(version) == 0; - } - - @Override - public int hashCode() { - return Arrays.hashCode(sequence); - } - - @Override - public String toString() { - return stringValue; - } -} diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/builder/BuildCommand.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/builder/BuildCommand.java index 98597cdcd..fa55d133e 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/builder/BuildCommand.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/builder/BuildCommand.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020, 2021, Oracle and/or its affiliates. +// Copyright (c) 2020, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.builder; @@ -17,8 +17,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.Stream; import com.oracle.weblogic.imagetool.logging.LoggingFacade; import com.oracle.weblogic.imagetool.logging.LoggingFactory; @@ -28,10 +26,12 @@ public class BuildCommand { private static final LoggingFacade logger = LoggingFactory.getLogger(BuildCommand.class); + private final String executable; private final List<String> command; private final List<BuildArg> buildArgs; private List<String> additionalOptions; private final String context; + private boolean useBuildx = false; /** * Create a build command for creating an image. At some point, it might @@ -41,7 +41,8 @@ public class BuildCommand { public BuildCommand(String buildEngine, String contextFolder) { Objects.requireNonNull(contextFolder); buildArgs = new ArrayList<>(); - command = Stream.of(buildEngine, "build", "--no-cache").collect(Collectors.toList()); + executable = buildEngine; + command = new ArrayList<>(); context = contextFolder; } @@ -59,6 +60,22 @@ public BuildCommand tag(String value) { return this; } + /** + * Add container build platform. Pass the desired + * build architecture to the build process. + * @param value a single platform name. + * @return this + */ + public BuildCommand platform(String value) { + if (Utils.isEmptyString(value)) { + return this; + } + command.add("--platform"); + command.add(value); + useBuildx = true; + return this; + } + /** * Always remove intermediate containers if set to true. * By default, Docker leaves intermediate containers when the build fails which is not ideal for CI/CD servers. @@ -237,7 +254,13 @@ private CloseableList<PrintWriter> createPrintWriters(List<OutputStream> outputS } private List<String> getCommand(boolean showPasswords) { - List<String> result = new ArrayList<>(command); + List<String> result = new ArrayList<>(); + result.add(executable); + if (useBuildx) { + result.add("buildx"); + } + result.add("build"); + result.addAll(command); if (additionalOptions != null && !additionalOptions.isEmpty()) { result.addAll(additionalOptions); } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cachestore/OPatchFile.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cachestore/OPatchFile.java index 30e93483d..58c2425fc 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cachestore/OPatchFile.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cachestore/OPatchFile.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020, 2022, Oracle and/or its affiliates. +// Copyright (c) 2020, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.cachestore; @@ -110,8 +110,11 @@ private static AruPatch getAruPatchOnline(String patchNumber, String providedVer throw new VersionNotFoundException(patchNumber, providedVersion, patches); } } else { - // Select the newest (highest numbered) patch - selectedPatch = patches.stream().max(Comparator.naturalOrder()).orElse(null); + // Compare the ARU OPatch patches using the patch version field, like 12.2.1.4.0 + Comparator<AruPatch> patchVersionComparator = + Comparator.comparing(AruPatch::version, Utils::compareVersionsNullsFirst); + // Select the newest (highest version) OPatch install/patch + selectedPatch = patches.stream().max(patchVersionComparator).orElse(null); } return selectedPatch; } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntry.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntry.java index 69947194b..79c4533f4 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntry.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntry.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2021, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.cli.cache; @@ -22,12 +22,27 @@ public CommandResponse call() throws CacheStoreException { if ("NONE".equalsIgnoreCase(version)) { throw new IllegalArgumentException("IMG-0105"); } - String key = String.format("%s%s%s", type, CacheStore.CACHE_KEY_SEPARATOR, version); - return addToCache(key); + + return addToCache(); + } + + @Override + public String getKey() { + StringBuilder key = new StringBuilder(25) + .append(type) + .append(CacheStore.CACHE_KEY_SEPARATOR) + .append(version); + + if (architecture != null) { + key.append(CacheStore.CACHE_KEY_SEPARATOR) + .append(architecture); + } + + return key.toString(); } @Option( - names = {"--type"}, + names = {"-t", "--type"}, description = "Type of installer. Valid values: ${COMPLETION-CANDIDATES}", required = true, defaultValue = "wls" @@ -35,10 +50,16 @@ public CommandResponse call() throws CacheStoreException { private InstallerType type; @Option( - names = {"--version"}, + names = {"-v", "--version"}, description = "Installer version. Ex: For WLS|FMW use 12.2.1.3.0 For jdk, use 8u201", required = true ) private String version; + @Option( + names = {"-a", "--architecture"}, + description = "(Optional) Installer architecture. Ex: linux/amd64 or linux/arm64." + ) + private String architecture; + } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java index 30bba608b..ff882d4b3 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java @@ -17,12 +17,16 @@ ) public class AddPatchEntry extends CacheAddOperation { + public String getKey() { + return patchId; + } + @Override public CommandResponse call() throws Exception { try { if (patchId != null && !patchId.isEmpty()) { Utils.validatePatchIds(Collections.singletonList(patchId), true); - return addToCache(patchId); + return addToCache(); } else { return CommandResponse.error("IMG-0076", "--patchId"); } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/CacheAddOperation.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/CacheAddOperation.java index 72ba91683..041de8a0d 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/CacheAddOperation.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/CacheAddOperation.java @@ -14,12 +14,15 @@ public abstract class CacheAddOperation extends CacheOperation { - CommandResponse addToCache(String key) throws CacheStoreException { + public abstract String getKey(); + + CommandResponse addToCache() throws CacheStoreException { // if file is invalid or does not exist, return an error if (filePath == null || !Files.isRegularFile(filePath)) { return CommandResponse.error("IMG-0049", filePath); } + String key = getKey(); // if the new value is the same as the existing cache value, do nothing String existingValue = cache().getValueFromCache(key); if (absolutePath().toString().equals(existingValue)) { @@ -36,7 +39,7 @@ CommandResponse addToCache(String key) throws CacheStoreException { return CommandResponse.success("IMG-0050", key, cache().getValueFromCache(key)); } - Path absolutePath() { + private Path absolutePath() { if (absolutePath == null) { absolutePath = filePath.toAbsolutePath(); } @@ -53,8 +56,8 @@ Path absolutePath() { @Option( - names = {"--path"}, - description = "Location on disk. For ex: /path/to/patch-or-installer.zip", + names = {"-p", "--path"}, + description = "Location of the file on disk. For ex: /path/to/patch-or-installer.zip", required = true ) private Path filePath; diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonCreateOptions.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonCreateOptions.java index 287bf0bbd..727c9ef0c 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonCreateOptions.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonCreateOptions.java @@ -1,4 +1,4 @@ -// Copyright (c) 2021, 2022, Oracle and/or its affiliates. +// Copyright (c) 2021, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.cli.menu; @@ -34,14 +34,14 @@ void prepareNewImage() throws IOException, InterruptedException, XPathExpression copyOptionsFromImage(); if (dockerfileOptions.installJava()) { - CachedFile jdk = new CachedFile(InstallerType.JDK, jdkVersion); + CachedFile jdk = new CachedFile(InstallerType.JDK, jdkVersion, getBuildPlatform()); Path installerPath = jdk.copyFile(cache(), buildDir()); dockerfileOptions.setJavaInstaller(installerPath.getFileName().toString()); } if (dockerfileOptions.installMiddleware()) { MiddlewareInstall install = - new MiddlewareInstall(getInstallerType(), installerVersion, installerResponseFiles); + new MiddlewareInstall(getInstallerType(), installerVersion, installerResponseFiles, getBuildPlatform()); install.copyFiles(cache(), buildDir()); dockerfileOptions.setMiddlewareInstall(install); } else { diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonOptions.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonOptions.java index b80f0cfcc..baae90368 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonOptions.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonOptions.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2022, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.cli.menu; @@ -122,6 +122,7 @@ BuildCommand getInitialBuildCmd(String contextFolder) { cmdBuilder.forceRm(!skipcleanup) .tag(imageTag) + .platform(buildPlatform) .network(buildNetwork) .pull(buildPull) .additionalOptions(buildOptions) @@ -312,6 +313,10 @@ public String buildId() { return buildId; } + public String getBuildPlatform() { + return buildPlatform; + } + @Option( names = {"--tag"}, paramLabel = "<image tag>", @@ -365,12 +370,14 @@ public String buildId() { @Option( names = {"--additionalBuildCommands"}, + paramLabel = "<filename>", description = "path to a file with additional build commands." ) private Path additionalBuildCommandsPath; @Option( names = {"--additionalBuildFiles"}, + paramLabel = "<filename>", split = ",", description = "comma separated list of files that should be copied to the build context folder." ) @@ -404,6 +411,7 @@ public String buildId() { @Option( names = {"--builder", "-b"}, + paramLabel = "<executable name>", description = "Executable to process the Dockerfile." + " Use the full path of the executable if not on your path." + " Defaults to 'docker', or, when set, to the value in environment variable WLSIMG_BUILDER." @@ -412,6 +420,7 @@ public String buildId() { @Option( names = {"--target"}, + paramLabel = "<target environment>", description = "Apply settings appropriate to the target environment. Default: ${DEFAULT-VALUE}." + " Supported values: ${COMPLETION-CANDIDATES}." ) @@ -419,10 +428,18 @@ public String buildId() { @Option( names = {"--build-arg"}, + paramLabel = "<arg=value>", description = "Additional argument passed directly to the build engine." ) Map<String,String> buildArgs; + @Option( + names = {"--platform"}, + paramLabel = "<target platform>", + description = "Set the target platform to build. Example: linux/amd64 or linux/arm64" + ) + private String buildPlatform; + @Parameters( description = "Container build options.", hidden = true diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/FmwInstallerType.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/FmwInstallerType.java index 740212f45..745a31f21 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/FmwInstallerType.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/FmwInstallerType.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2023, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.installer; @@ -82,6 +82,9 @@ public enum FmwInstallerType { OHS(Utils.toSet(AruProduct.OHS, AruProduct.OAM_WG, AruProduct.WLS, AruProduct.JDBC, AruProduct.FMWPLAT, AruProduct.OSS, AruProduct.FIT), InstallerType.OHS), + OHS_DB19(Utils.toSet(AruProduct.OHS, AruProduct.OAM_WG, AruProduct.WLS, AruProduct.JDBC, AruProduct.FMWPLAT, + AruProduct.OSS, AruProduct.FIT), + InstallerType.OHS, InstallerType.DB19), ODI(Collections.singleton(AruProduct.ODI), InstallerType.ODI) ; diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/InstallerType.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/InstallerType.java index 8f6e2015a..d58f354d4 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/InstallerType.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/InstallerType.java @@ -20,6 +20,7 @@ public enum InstallerType { IDM("idm"), OAM("oam"), OHS("ohs"), + DB19("db19"), OUD("oud"), OID("oid"), WCC("wcc"), diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstall.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstall.java index 5518d569e..c9603e309 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstall.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstall.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2021, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.installer; @@ -8,6 +8,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; @@ -30,7 +31,7 @@ public class MiddlewareInstall { * Get the install metadata for a given middleware install type. * @param type the requested middleware install type */ - public MiddlewareInstall(FmwInstallerType type, String version, List<Path> responseFiles) + public MiddlewareInstall(FmwInstallerType type, String version, List<Path> responseFiles, String buildPlatform) throws FileNotFoundException { logger.info("IMG-0039", type.installerListString(), version); @@ -39,8 +40,11 @@ public MiddlewareInstall(FmwInstallerType type, String version, List<Path> respo for (InstallerType installer : type.installerList()) { MiddlewareInstallPackage pkg = new MiddlewareInstallPackage(); pkg.type = installer; - pkg.installer = new CachedFile(installer, version); + pkg.installer = new CachedFile(installer, version, buildPlatform); pkg.responseFile = new DefaultResponseFile(installer, type); + if (installer.equals(InstallerType.DB19)) { + pkg.preinstallCommands = Collections.singletonList("34761383/changePerm.sh /u01/oracle"); + } addInstaller(pkg); } setResponseFiles(responseFiles); diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstallPackage.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstallPackage.java index e7bf9c808..2cb06550f 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstallPackage.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstallPackage.java @@ -1,8 +1,10 @@ -// Copyright (c) 2020, 2021, Oracle and/or its affiliates. +// Copyright (c) 2020, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.installer; +import java.util.List; + import com.oracle.weblogic.imagetool.api.model.CachedFile; public class MiddlewareInstallPackage { @@ -11,6 +13,7 @@ public class MiddlewareInstallPackage { CachedFile installer; String installerFilename; String jarName; + List<String> preinstallCommands; boolean isZip = true; boolean isBin = false; } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/BuildPlatform.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/BuildPlatform.java new file mode 100644 index 000000000..46649afd6 --- /dev/null +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/BuildPlatform.java @@ -0,0 +1,58 @@ +// Copyright (c) 2024, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +package com.oracle.weblogic.imagetool.util; + +import com.oracle.weblogic.imagetool.logging.LoggingFacade; +import com.oracle.weblogic.imagetool.logging.LoggingFactory; + +public class BuildPlatform { + private static final LoggingFacade logger = LoggingFactory.getLogger(BuildPlatform.class); + + public static final String ARM64 = "linux/arm64"; + public static final String AMD64 = "linux/amd64"; + + public static final String OS_ARCH; + + static { + OS_ARCH = System.getProperty("os.arch"); + logger.fine("Local machine architecture is {0}", OS_ARCH); + } + + private BuildPlatform() { + // just static methods for now + } + + /** + * Get the build platform name using System property "os.arch". + * @return name of the build platform, like linux/amd64. + */ + public static String getPlatformName() { + return getPlatformName(OS_ARCH); + } + + /** + * Get the build platform name using the provided architecture name. + * @return name of the build platform, like linux/amd64. + */ + public static String getPlatformName(String architecture) { + logger.entering(architecture); + String result; + switch (architecture) { + case "arm64": + case "aarch64": + result = ARM64; + break; + case "amd64": + case "x86_64": + result = AMD64; + break; + default: + // this can occur when the JDK provides an unknown ID for the OS in the system property os.arch + logger.warning("Unsupported architecture type {0}, defaulting to amd64"); + result = AMD64; + } + logger.exiting(result); + return result; + } +} diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/HttpUtil.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/HttpUtil.java index f12f71eea..ff9a5ca26 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/HttpUtil.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/HttpUtil.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2022, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.util; @@ -182,18 +182,12 @@ private static HttpRequestRetryHandler retryHandler() { // Do not retry if over max retries return false; } - if (exception instanceof InterruptedIOException) { - // Timeout - return false; - } - if (exception instanceof UnknownHostException) { - // Unknown host - return false; - } - if (exception instanceof SSLException) { - // SSL handshake failed + if (exception instanceof InterruptedIOException // Timeout + || exception instanceof UnknownHostException // Unknown Host + || exception instanceof SSLException) { // SSL handshake failed return false; } + HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); // return true if it is okay to retry this request type diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java index dd9f1da38..2c2e88a30 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2021, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.util; @@ -303,6 +303,27 @@ public static void deleteFilesRecursively(String pathDir) throws IOException { logger.exiting(); } + /** + * Compares two version strings. A null-friendly comparator that considers null to be less than non-null. + * Any qualifiers are treated as older than the same version without + * a qualifier. If both versions have qualifiers and are otherwise equal, they are compared using + * String.compareTo() to determine the result. + * + * @param thisVersion - first version + * @param otherVersion - second version + * @return returns 0 if the versions are equal, greater than zero if thisVersion is newer, + * and less than zero if thisVersion is older. + */ + public static int compareVersionsNullsFirst(String thisVersion, String otherVersion) { + if (isEmptyString(thisVersion)) { + return (isEmptyString(otherVersion)) ? 0 : -1; + } else if (isEmptyString(otherVersion)) { + return 1; + } else { + return compareVersions(thisVersion, otherVersion); + } + } + /** * Compares two version strings. Any qualifiers are treated as older than the same version without * a qualifier. If both versions have qualifiers and are otherwise equal, they are compared using @@ -314,8 +335,6 @@ public static void deleteFilesRecursively(String pathDir) throws IOException { * and less than zero if thisVersion is older. */ public static int compareVersions(String thisVersion, String otherVersion) { - int result = 0; - if (isEmptyString(thisVersion) || isEmptyString(otherVersion)) { throw new IllegalArgumentException("cannot compare null strings"); } @@ -330,24 +349,22 @@ public static int compareVersions(String thisVersion, String otherVersion) { int fieldsToCompare = Math.min(thisVersionElements.length, otherVersionElements.length); + int result = 0; int idx; for (idx = 0; idx < fieldsToCompare; idx++) { int thisVersionNumber = Integer.parseInt(thisVersionElements[idx]); int otherVersionNumber = Integer.parseInt(otherVersionElements[idx]); - if (thisVersionNumber > otherVersionNumber) { - result = 1; - break; - } else if (thisVersionNumber < otherVersionNumber) { - result = -1; - break; + result = Integer.compare(thisVersionNumber, otherVersionNumber); + if (result != 0) { + return result; } } // Version fields compared so far are equal so check to see if one version number // has more fields than the other. // - if (result == 0 && thisVersionElements.length != otherVersionElements.length) { + if (thisVersionElements.length != otherVersionElements.length) { if (thisVersionElements.length > otherVersionElements.length) { result = 1; } else { @@ -355,36 +372,37 @@ public static int compareVersions(String thisVersion, String otherVersion) { } } + if (result != 0) { + return result; + } + // Finally, look to see if one or both versions have a qualifier if they are otherwise the same. // - if (result == 0) { - int useCase = 0; - if (thisVersion.indexOf('-') != -1) { - useCase += 1; - } - if (otherVersion.indexOf('-') != -1) { - useCase += 2; - } - switch (useCase) { - case 0: - break; + int useCase = 0; + if (thisVersion.indexOf('-') != -1) { + useCase += 1; + } + if (otherVersion.indexOf('-') != -1) { + useCase += 2; + } + switch (useCase) { + case 1: + result = -1; + break; - case 1: - result = -1; - break; + case 2: + result = 1; + break; - case 2: - result = 1; - break; + case 3: + String thisQualifier = thisVersion.substring(thisVersion.indexOf('-')); + String otherQualifier = otherVersion.substring(otherVersion.indexOf('-')); + result = thisQualifier.compareTo(otherQualifier); + break; - case 3: - String thisQualifier = thisVersion.substring(thisVersion.indexOf('-')); - String otherQualifier = otherVersion.substring(otherVersion.indexOf('-')); - result = thisQualifier.compareTo(otherQualifier); - break; - default: - break; - } + case 0: + default: + break; } return result; } diff --git a/imagetool/src/main/resources/docker-files/install-middleware.mustache b/imagetool/src/main/resources/docker-files/install-middleware.mustache index a53322a02..f472c60d3 100644 --- a/imagetool/src/main/resources/docker-files/install-middleware.mustache +++ b/imagetool/src/main/resources/docker-files/install-middleware.mustache @@ -1,4 +1,4 @@ -# Copyright (c) 2021, Oracle and/or its affiliates. +# Copyright (c) 2021, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # # Installing Middleware @@ -36,17 +36,26 @@ USER {{userid}} RUN echo "INSTALLING MIDDLEWARE" \ {{#installPackages}} - && echo "INSTALLING {{type}}" \ - && {{#isZip}}unzip -q {{{tempDir}}}/{{installerFilename}} "*.[jb][ai][rn]" -d {{{tempDir}}} &&{{/isZip}} \ - {{^isBin}}{{{java_home}}}/bin/java -Xmx1024m -jar {{{tempDir}}}/{{jarName}} -silent ORACLE_HOME={{{oracle_home}}} \ - -responseFile {{{tempDir}}}/{{responseFile.name}} -invPtrLoc {{inv_loc}}/oraInst.loc -ignoreSysPrereqs -force -novalidation {{/isBin}} \ - {{#isBin}}chmod +x {{{tempDir}}}/{{jarName}} && \ - {{{tempDir}}}/{{jarName}} -force -ignoreSysPrereqs -silent -responseFile {{{tempDir}}}/{{responseFile.name}} \ - -invPtrLoc {{inv_loc}}/oraInst.loc ORACLE_HOME={{{oracle_home}}} -jreLoc {{{java_home}}} {{/isBin}} \ + && echo "INSTALLING {{type}}" \ + # If installer is packaged in a ZIP, extract it before running it + {{#isZip}}&& unzip -q {{{tempDir}}}/{{installerFilename}} -d {{{tempDir}}}/{{{type}}} {{/isZip}} \ + {{#preinstallCommands}}&& {{{tempDir}}}/{{{type}}}/{{{.}}} {{/preinstallCommands}} \ + # IF the installer is a JAR file (not a .bin), run the silent install using Java + {{^isBin}} && {{{java_home}}}/bin/java -Xmx1024m -jar {{{tempDir}}}/{{{type}}}/{{jarName}} \ + -silent ORACLE_HOME={{{oracle_home}}} \ + -responseFile {{{tempDir}}}/{{responseFile.name}} \ + -invPtrLoc {{inv_loc}}/oraInst.loc \ + -ignoreSysPrereqs -force -novalidation {{/isBin}} \ + # If the installer is a BIN, make sure it is executable and run the installer + {{#isBin}} && chmod +x {{{tempDir}}}/{{{type}}}/{{jarName}} \ + && {{{tempDir}}}/{{{type}}}/{{jarName}} \ + -force -ignoreSysPrereqs -silent \ + -responseFile {{{tempDir}}}/{{responseFile.name}} \ + -invPtrLoc {{inv_loc}}/oraInst.loc ORACLE_HOME={{{oracle_home}}} -jreLoc {{{java_home}}} {{/isBin}} \ {{/installPackages}} -&& test $? -eq 0 \ -&& chmod -R g+r {{{oracle_home}}} \ -|| (grep -vh "NOTIFICATION" /tmp/OraInstall*/install*.log && exit 1) + && test $? -eq 0 \ + && chmod -R g+r {{{oracle_home}}} \ + || (grep -vh "NOTIFICATION" /tmp/OraInstall*/install*.log && exit 1) {{> fmw-patching}} diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/aru/VersionTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/aru/VersionTest.java deleted file mode 100644 index f0c135c56..000000000 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/aru/VersionTest.java +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2023, Oracle and/or its affiliates. -// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. - -package com.oracle.weblogic.imagetool.aru; - -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -@Tag("unit") -class VersionTest { - @Test - void sameVersionNumber() { - Version a = new Version("1.2.3"); - Version b = new Version("1.2.3"); - assertEquals(0, b.compareTo(a)); - assertEquals(0, a.compareTo(b)); - } - - private void compareDifferingVersions(String firstVersion, String laterVersion) { - Version v1 = new Version(firstVersion); - Version v2 = new Version(laterVersion); - assertEquals(1, v2.compareTo(v1)); - assertEquals(-1, v1.compareTo(v2)); - } - - @Test - void differentVersionNumbers() { - compareDifferingVersions("1.2.3", "1.2.4"); - } - - @Test - void differentVersionLengths() { - compareDifferingVersions("1.2.3", "1.2.3.1"); - } - - @Test - void integerComparison() { - compareDifferingVersions("13.9.4.2.9", "13.9.4.2.10"); - } - - @Test - void nullVersion() { - compareDifferingVersions(null, "1.2.3"); - } - - @Test - void nonNumericVersion() { - assertThrows(NumberFormatException.class, () -> new Version("1.A.4")); - assertThrows(NumberFormatException.class, () -> new Version("1.2.3-SNAP")); - } - - @Test - void allowsNull() { - Version a = new Version(null); - Version b = new Version("1.2.3"); - assertEquals(1, b.compareTo(a)); - assertEquals(-1, a.compareTo(b)); - } - - @Test - void equalObjects() { - Version a = new Version("1.2.3"); - Version b = new Version("1.2.3"); - assertEquals(a, b); - assertEquals(b, a); - assertEquals(a, a); - assertNotEquals(a, null); - } - - @Test - void hashcodeTest() { - Version a = new Version("1.2.3"); - Version b = new Version("1.2.3"); - Version c = new Version("1.2.4"); - assertEquals(a.hashCode(), b.hashCode()); - assertNotEquals(a.hashCode(), c.hashCode()); - } -} diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/builder/BuilderTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/builder/BuilderTest.java index 7d98fdcc8..bfd029ce7 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/builder/BuilderTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/builder/BuilderTest.java @@ -1,4 +1,4 @@ -// Copyright (c) 2021, Oracle and/or its affiliates. +// Copyright (c) 2021, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.builder; @@ -17,7 +17,7 @@ class BuilderTest { private static final String BUILD_ENGINE = "docker"; private String expected(String options) { - return String.format("%s build --no-cache %s %s", BUILD_ENGINE, options, BUILD_CONTEXT); + return String.format("%s build %s %s", BUILD_ENGINE, options, BUILD_CONTEXT); } @Test diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/CachedFileTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/CachedFileTest.java index a44e904f5..be2b5239f 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/CachedFileTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/CachedFileTest.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020, 2021, Oracle and/or its affiliates. +// Copyright (c) 2020, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.cachestore; @@ -17,6 +17,7 @@ import com.oracle.weblogic.imagetool.installer.InstallerType; import com.oracle.weblogic.imagetool.logging.LoggingFacade; import com.oracle.weblogic.imagetool.logging.LoggingFactory; +import com.oracle.weblogic.imagetool.util.BuildPlatform; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -25,6 +26,8 @@ import static com.oracle.weblogic.imagetool.cachestore.OPatchFile.DEFAULT_BUG_NUM; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertLinesMatch; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @Tag("unit") @@ -33,54 +36,105 @@ class CachedFileTest { static Path cacheDir; static CacheStore cacheStore; static final List<String> fileContents = Arrays.asList("A", "B", "C"); - static final String SOME_VERSION = "12.2.1.3.0"; + static final String ver12213 = "12.2.1.3.0"; @BeforeAll static void setup(@TempDir Path tempDir, @TempDir Path cacheDir) throws IOException { + Path path12213 = tempDir.resolve("installer.file.122130.jar"); + Files.write(path12213, fileContents); + Path path12214 = tempDir.resolve("installer.file.12214.jar"); + Files.write(path12214, fileContents); + Path path1411 = tempDir.resolve("installer.file.141100.jar"); + Files.write(path1411, fileContents); + CachedFileTest.cacheDir = cacheDir; cacheStore = new CacheStoreTestImpl(cacheDir); - // build a fake cache with two installers - String key1 = "wls_" + SOME_VERSION; - Path path1 = tempDir.resolve("installer.file.122130.jar"); - Files.write(path1, fileContents); - cacheStore.addToCache(key1, path1.toString()); - cacheStore.addToCache("wls_12.2.1.4.0", "/dont/care"); + // build a fake cache with several installers + cacheStore.addToCache("wls_" + ver12213, path12213.toString()); + cacheStore.addToCache("wls_12.2.1.4.0_" + BuildPlatform.getPlatformName(), path12214.toString()); + cacheStore.addToCache("wls_14.1.1.0.0_amd64", path1411.toString()); // OPatch files - cacheStore.addToCache(DEFAULT_BUG_NUM + "_13.9.2.0.0", "/dont/care"); - cacheStore.addToCache(DEFAULT_BUG_NUM + "_13.9.4.0.0", "/dont/care"); - cacheStore.addToCache(DEFAULT_BUG_NUM + "_13.9.2.2.2", "/dont/care"); + cacheStore.addToCache(DEFAULT_BUG_NUM + "_13.9.2.0.0", "/not/used"); + cacheStore.addToCache(DEFAULT_BUG_NUM + "_13.9.4.0.0", "/not/used"); + cacheStore.addToCache(DEFAULT_BUG_NUM + "_13.9.2.2.2", "/not/used"); } @Test void versionString() { - CachedFile wlsInstallerFile = new CachedFile(InstallerType.WLS, SOME_VERSION); - - assertEquals("wls_" + SOME_VERSION, wlsInstallerFile.getKey(), - "Cached file getKey failed for WLS installer"); + CachedFile wlsInstallerFile = new CachedFile(InstallerType.WLS, "12.2.1.3.0"); - assertEquals(SOME_VERSION, wlsInstallerFile.getVersion(), "CachedFile returned wrong version"); + assertEquals("wls_12.2.1.3.0", wlsInstallerFile.getKey(), + "CachedFile getKey() did not construct the cache key correctly"); + assertEquals("12.2.1.3.0", wlsInstallerFile.getVersion(), + "CachedFile should return the version from the constructor"); + } - // if the file ID has the version separator, CachedFile should ignore the version passed, and use the version - // in the ID. - CachedFile cf = new CachedFile("something_versionString", SOME_VERSION); + @Test + void userProvidedPatchVersionAsId() { + // User provided a patch ID with the version string in the ID + CachedFile cf = new CachedFile("something_versionString", "12.2.1.2.0"); + // if the patch ID has the version, CachedFile should ignore the installer version passed to the constructor, + // and use the version in the ID. assertEquals("something_versionString", cf.getKey(), - "Cached file getKey failed for version string"); + "CachedFile getKey() failed when version string was provided by the user in the ID"); // getVersion should always return the version that was provided in the constructor, not the one in the ID - assertEquals(SOME_VERSION, cf.getVersion(), "CachedFile returned wrong version"); + assertEquals("12.2.1.2.0", cf.getVersion(), "CachedFile returned wrong version"); } @Test - void resolveFile() throws Exception { + void resolveFileNotFound() throws Exception { // resolve should fail for a CachedFile that is not in the store CachedFile fakeFile = new CachedFile(InstallerType.WLS, "10.3.6.0.0"); assertThrows(FileNotFoundException.class, () -> fakeFile.resolve(cacheStore)); + } + + @Test + void resolveFileFindsFile() throws IOException { + // Resolve a CachedFile stored in the cache (created in test setup above) + CachedFile wlsInstallerFile = new CachedFile(InstallerType.WLS, ver12213); + String expected = cacheStore.getValueFromCache("wls_" + ver12213); + assertEquals(expected, wlsInstallerFile.resolve(cacheStore), "CachedFile did not resolve file"); + } + + @Test + void resolveNoArchFile() throws IOException { + // Look for a cache entry where the user specified the architecture/platform amd64 + CachedFile wlsNoArch = new CachedFile(InstallerType.WLS, ver12213, "amd64"); + + // verify the cache is setup as expected. + // wls_12.2.1.3.0 is in the cache, but wls_12.2.1.3.0_amd64 is NOT in the cache + assertNull(cacheStore.getValueFromCache("wls_12.2.1.3.0_amd64")); + String expected = cacheStore.getValueFromCache("wls_12.2.1.3.0"); + assertNotNull(expected); + + assertEquals(expected, wlsNoArch.resolve(cacheStore), "CachedFile returned wrong file"); + } + + @Test + void resolveWithArchitecture() throws IOException { + // Look for a cache entry where the user specified the architecture/platform amd64 + CachedFile wlsArch = new CachedFile(InstallerType.WLS, "14.1.1.0.0", "amd64"); + + // verify the cache is setup as expected. wls_14.1.1.0.0_amd64 is in the cache + String expected = cacheStore.getValueFromCache("wls_14.1.1.0.0_amd64"); + assertNotNull(expected); + + assertEquals(expected, wlsArch.resolve(cacheStore), "CachedFile failed to find specific architecture"); + } + + @Test + void resolveFallbackToLocalArch() throws IOException { + // Look for a cache entry where the user did not specify the architecture/platform + CachedFile wlsArch = new CachedFile(InstallerType.WLS, "12.2.1.4.0"); + + // verify the cache is setup as expected. wls_14.1.1.0.0_amd64 is in the cache, but wls_14.1.1.0.0 is not + assertNull(cacheStore.getValueFromCache("wls_12.2.1.4.0")); + String expected = cacheStore.getValueFromCache("wls_12.2.1.4.0_" + BuildPlatform.getPlatformName()); + assertNotNull(expected); - // CachedFile resolve should result in the same behavior has getting the path from the cache store - CachedFile wlsInstallerFile = new CachedFile(InstallerType.WLS, SOME_VERSION); - String expected = cacheStore.getValueFromCache("wls_" + SOME_VERSION); - assertEquals(expected, wlsInstallerFile.resolve(cacheStore), "resolve failed for CachedFile"); + assertEquals(expected, wlsArch.resolve(cacheStore), "CachedFile failed to check local architecture"); } @Test @@ -89,7 +143,7 @@ void copyFile(@TempDir Path contextDir) throws Exception { Level oldLevel = logger.getLevel(); logger.setLevel(Level.OFF); try { - CachedFile wlsInstallerFile = new CachedFile(InstallerType.WLS, SOME_VERSION); + CachedFile wlsInstallerFile = new CachedFile(InstallerType.WLS, ver12213); // copy the file from the cache store to the fake build context directory Path result = wlsInstallerFile.copyFile(cacheStore, contextDir.toString()); // check to see if the file was copied correctly by examining the contents of the resulting file diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java index 9bb60e4ad..41cdd0af1 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java @@ -1,4 +1,4 @@ -// Copyright (c) 2020, 2022, Oracle and/or its affiliates. +// Copyright (c) 2020, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.cachestore; @@ -404,6 +404,7 @@ void opatchNoRecommendedTest() throws Exception { String patchId = "2818673x"; OPatchFile patchFile = OPatchFile.getInstance(patchId, "x", "x", cacheStore); + assertEquals("13.9.4.2.5", patchFile.getVersion()); String filePath = patchFile.resolve(cacheStore); assertNotNull(filePath, "Patch resolve() failed to get file path from XML"); diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntryTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntryTest.java index d05816af0..ff9d21f2b 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntryTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntryTest.java @@ -1,67 +1,69 @@ -// Copyright (c) 2019, 2021, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.cli.cache; -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; - -import com.oracle.weblogic.imagetool.api.model.CommandResponse; -import com.oracle.weblogic.imagetool.cli.ImageTool; import com.oracle.weblogic.imagetool.installer.InstallerType; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import picocli.CommandLine; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @Tag("unit") class AddInstallerEntryTest { - - private ByteArrayOutputStream byteArrayOutputStream = null; - private PrintWriter printStream = null; - - @BeforeEach - void setup() { - byteArrayOutputStream = new ByteArrayOutputStream(); - printStream = new PrintWriter(byteArrayOutputStream); - } - - @AfterEach - void teardown() { - if (printStream != null) { - printStream.close(); - } - } - @Test void testMissingParameters() { - ImageTool.run(new AddInstallerEntry(), printStream, printStream); - assertTrue(new String(byteArrayOutputStream.toByteArray()).contains("Missing required options")); + final AddInstallerEntry addCommand = new AddInstallerEntry(); + // Empty command line throws exception because the required parameters were not specified + assertThrows(CommandLine.MissingParameterException.class, () -> + new CommandLine(addCommand).parseArgs() + ); } @Test void testWrongType() { - ImageTool.run(new AddInstallerEntry(), printStream, printStream, - "--type", "a2z", "--version", "some_value", "--path", "/path/to/a/file"); - assertTrue(new String(byteArrayOutputStream.toByteArray()).contains( - "Invalid value for option '--type'")); + final AddInstallerEntry addCommand = new AddInstallerEntry(); + // The value for --type must be one of the pre-defined types + CommandLine.ParameterException pe = assertThrows(CommandLine.ParameterException.class, () -> + new CommandLine(addCommand) + .parseArgs("--type", "a2z", "--version", "some_value", "--path", "/path/to/a/file") + ); + assertTrue(pe.getMessage().contains("--type")); + + // repeat same command but use a valid type. No exception should be thrown. + new CommandLine(addCommand) + .parseArgs("--type", "WLS", "--version", "some_value", "--path", "/path/to/a/file"); } @Test void testMissingVersion() { - ImageTool.run(new AddInstallerEntry(), printStream, printStream, - "--type", InstallerType.WLS.toString(), "--path", "/path/to/a/file"); - assertTrue(new String(byteArrayOutputStream.toByteArray()).contains( - "Missing required option: '--version=<version>'")); + final AddInstallerEntry addCommand = new AddInstallerEntry(); + // The value for --version must be specified + CommandLine.ParameterException pe = assertThrows(CommandLine.ParameterException.class, () -> + new CommandLine(addCommand) + .parseArgs("--type", InstallerType.WLS.toString(), "--path", "/path/to/a/file") + ); + assertTrue(pe.getMessage().contains("--version")); + } + + @Test + void testValidParameters() { + final AddInstallerEntry addCommand = new AddInstallerEntry(); + // The cache key should be a string made up of the type and version seperated by an underscore + new CommandLine(addCommand) + .parseArgs("--type", "WLS", "--version", "12.2.1.4", "--path", "/path/to/a/file"); + assertEquals("wls_12.2.1.4", addCommand.getKey()); } @Test - void testInvalidParameters() { - CommandResponse response = ImageTool.run(new AddInstallerEntry(), printStream, printStream, "--type", - InstallerType.WLS.toString(), "--version", "", "--path", "/path/to/non/existent/file"); - assertEquals(1, response.getStatus()); + void testArchKey() { + final AddInstallerEntry addCommand = new AddInstallerEntry(); + // The cache key should be a string made up of the type, version, and architecture seperated by an underscore + new CommandLine(addCommand) + .parseArgs("--type", "WLS", "--version", "12.2.1.4", "-a", "amd64", "--path", "/path/to/a/file"); + assertEquals("wls_12.2.1.4_amd64", addCommand.getKey()); } } diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstallTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstallTest.java new file mode 100644 index 000000000..e357ebfeb --- /dev/null +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/installer/MiddlewareInstallTest.java @@ -0,0 +1,90 @@ +// Copyright (c) 2024, Oracle and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +package com.oracle.weblogic.imagetool.installer; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; + +import com.oracle.weblogic.imagetool.ResourceUtils; +import com.oracle.weblogic.imagetool.cachestore.CacheStore; +import com.oracle.weblogic.imagetool.cachestore.CacheStoreTestImpl; +import com.oracle.weblogic.imagetool.logging.LoggingFacade; +import com.oracle.weblogic.imagetool.logging.LoggingFactory; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Tag("unit") +class MiddlewareInstallTest { + static Path cacheDir; + static CacheStore cacheStore; + private static final LoggingFacade commandLogger = LoggingFactory.getLogger(MiddlewareInstall.class); + private static Level oldLevel; + + @BeforeAll + static void setup(@TempDir Path cacheDir) throws IOException { + oldLevel = commandLogger.getLevel(); + commandLogger.setLevel(Level.WARNING); + + MiddlewareInstallTest.cacheDir = cacheDir; + cacheStore = new CacheStoreTestImpl(cacheDir); + cacheStore.addToCache("wls_12.2.1.4.0", + ResourceUtils.resourcePath("/dummyInstallers/test-installer.zip").toString()); + } + + @AfterAll + static void tearDown() { + commandLogger.setLevel(oldLevel); + } + + @Test + void copyInstaller(@TempDir Path buildContextDir) throws IOException { + // Test a simple WLS install type, and copy the files to the build context folder + MiddlewareInstall install = new MiddlewareInstall(FmwInstallerType.WLS, "12.2.1.4.0", null, null); + install.copyFiles(cacheStore, buildContextDir.toString()); + // 2 files should be copied from cache to build context folder + assertTrue(Files.isRegularFile(buildContextDir.resolve("test-installer.zip"))); + assertTrue(Files.isRegularFile(buildContextDir.resolve("wls.rsp")), "Response file not found"); + // JAR name from inside the zip should be correctly identified + List<MiddlewareInstallPackage> installers = install.getInstallers(); + assertEquals(1, installers.size()); + + MiddlewareInstallPackage pkg = installers.get(0); + assertTrue(pkg.isZip); + assertEquals("the-installer.jar", pkg.jarName); + assertEquals("wls.rsp", pkg.responseFile.name()); + assertInstanceOf(DefaultResponseFile.class, pkg.responseFile); + } + + @Test + void customResponseFile(@TempDir Path buildContextDir) throws IOException { + List<Path> customResponse = + Collections.singletonList(ResourceUtils.resourcePath("/dummyInstallers/dummyResponse.txt")); + // Test a simple WLS install type, and copy the files to the build context folder + MiddlewareInstall install = new MiddlewareInstall(FmwInstallerType.WLS, "12.2.1.4.0", customResponse, null); + install.copyFiles(cacheStore, buildContextDir.toString()); + // 2 files should be copied from cache to build context folder + assertTrue(Files.isRegularFile(buildContextDir.resolve("test-installer.zip"))); + assertTrue(Files.isRegularFile(buildContextDir.resolve("dummyResponse.txt")), "Response file not found"); + // JAR name from inside the zip should be correctly identified + List<MiddlewareInstallPackage> installers = install.getInstallers(); + assertEquals(1, installers.size()); + + MiddlewareInstallPackage pkg = installers.get(0); + assertTrue(pkg.isZip); + assertEquals("the-installer.jar", pkg.jarName); + assertEquals("dummyResponse.txt", pkg.responseFile.name()); + assertInstanceOf(ProvidedResponseFile.class, pkg.responseFile); + } +} diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/DockerfileBuilderTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/DockerfileBuilderTest.java index 298c12139..64aae8c9e 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/DockerfileBuilderTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/DockerfileBuilderTest.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2021, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.util; @@ -28,7 +28,7 @@ class DockerfileBuilderTest { */ @Test void validateMustacheAliases() throws IOException { - MiddlewareInstall install = new MiddlewareInstall(FmwInstallerType.WLS, "12.2.1.3", null); + MiddlewareInstall install = new MiddlewareInstall(FmwInstallerType.WLS, "12.2.1.3", null, null); DockerfileOptions dockerfileOptions = new DockerfileOptions("123") .setPatchingEnabled() diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/UtilsTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/UtilsTest.java index 92a0c6be9..a869d28fe 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/UtilsTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/util/UtilsTest.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2022, Oracle and/or its affiliates. +// Copyright (c) 2019, 2024, Oracle and/or its affiliates. // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. package com.oracle.weblogic.imagetool.util; @@ -43,10 +43,117 @@ class UtilsTest { private SystemProperties overrideProperties; @Test - void compareVersions() { - assertEquals(0, Utils.compareVersions("12.2.1.3.0", "12.2.1.3.0")); - assertTrue(Utils.compareVersions("1.0", "1.1") < 0); - assertTrue(Utils.compareVersions("1.1", "1.0") > 0); + void firstGreaterThanLast() throws Exception { + String thisVersion = "12.2.1.3.0"; + String thatVersion = "12.2.1.2.0"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + + thisVersion = "0.7.4"; + thatVersion = "0.7.3"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + + thisVersion = "0.8"; + thatVersion = "0.7.4"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + + thisVersion = "1.2.3"; + thatVersion = "1.2"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + + thisVersion = "13.9.4.2.10"; + thatVersion = "13.9.4.2.9"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + + thisVersion = "1.2.3"; + thatVersion = "1.2.3-SNAPSHOT"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + + thisVersion = "1.2.3-BETA1"; + thatVersion = "1.2.3-ALPHA3"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + + thisVersion = "1.2.3-SNAPSHOT"; + thatVersion = "1.2.2"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) > 0, + "Expected this " + thisVersion + " to be newer than that " + thatVersion); + } + + @Test + void secondGreaterThanFirst() throws Exception { + String thisVersion = "12.2.1.3.0"; + String thatVersion = "12.2.1.4.0"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) < 0, + "Expected that " + thatVersion + " to be newer than this " + thisVersion); + + thisVersion = "0.7.3"; + thatVersion = "0.7.4"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) < 0, + "Expected that " + thatVersion + " to be newer than this " + thisVersion); + + thisVersion = "0.7.4"; + thatVersion = "1"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) < 0, + "Expected that " + thatVersion + " to be newer than this " + thisVersion); + + thisVersion = "1.2"; + thatVersion = "1.2.3"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) < 0, + "Expected that " + thatVersion + " to be newer than this " + thisVersion); + + thisVersion = "1.2.3-SNAPSHOT"; + thatVersion = "1.2.3"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) < 0, + "Expected that " + thatVersion + " to be newer than this " + thisVersion); + + thisVersion = "1.2.3-ALPHA4"; + thatVersion = "1.2.3-ALPHA5"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) < 0, + "Expected that " + thatVersion + " to be newer than this " + thisVersion); + + thisVersion = "1.2.1"; + thatVersion = "1.2.2-SNAPSHOT"; + assertTrue(Utils.compareVersions(thisVersion, thatVersion) < 0, + "Expected that " + thatVersion + " to be newer than this " + thisVersion); + } + + @Test + void versionsShouldBeEqual() throws Exception { + String thisVersion = "12.2.1.3.0"; + String thatVersion = "12.2.1.3.0"; + assertEquals(0, Utils.compareVersions(thisVersion, thatVersion), + "Expected server " + thatVersion + " to be the same as client " + thisVersion); + + thisVersion = "0.7.4"; + thatVersion = "0.7.4"; + assertEquals(0, Utils.compareVersions(thisVersion, thatVersion), + "Expected server " + thatVersion + " to be the same as client " + thisVersion); + + thisVersion = "1"; + thatVersion = "1"; + assertEquals(0, Utils.compareVersions(thisVersion, thatVersion), + "Expected server " + thatVersion + " to be the same as client " + thisVersion); + + thisVersion = "1.2.3-ALPHA1"; + thatVersion = "1.2.3-ALPHA1"; + assertEquals(0, Utils.compareVersions(thisVersion, thatVersion), + "Expected server " + thatVersion + " to be the same as client " + thisVersion); + + thisVersion = "1.2.3.4.5.6.7.8.9"; + thatVersion = "1.2.3.4.5.6.7.8.9"; + assertEquals(0, Utils.compareVersions(thisVersion, thatVersion), + "Expected server " + thatVersion + " to be the same as client " + thisVersion); + + thisVersion = "0.7.4-SNAPSHOT"; + thatVersion = "0.7.4-SNAPSHOT"; + assertEquals(0, Utils.compareVersions(thisVersion, thatVersion), + "Expected server " + thatVersion + " to be the same as client " + thisVersion); } @Test diff --git a/imagetool/src/test/resources/dummyInstallers/dummyResponse.txt b/imagetool/src/test/resources/dummyInstallers/dummyResponse.txt new file mode 100644 index 000000000..2995a4d0e --- /dev/null +++ b/imagetool/src/test/resources/dummyInstallers/dummyResponse.txt @@ -0,0 +1 @@ +dummy \ No newline at end of file diff --git a/imagetool/src/test/resources/dummyInstallers/test-installer.zip b/imagetool/src/test/resources/dummyInstallers/test-installer.zip new file mode 100644 index 000000000..f87e0b812 Binary files /dev/null and b/imagetool/src/test/resources/dummyInstallers/test-installer.zip differ diff --git a/imagetool/src/test/resources/patches/patch-2818673x.xml b/imagetool/src/test/resources/patches/patch-2818673x.xml index 22888e82c..695483759 100644 --- a/imagetool/src/test/resources/patches/patch-2818673x.xml +++ b/imagetool/src/test/resources/patches/patch-2818673x.xml @@ -1,10 +1,56 @@ -<!-- Copyright (c) 2020, 2021, Oracle and/or its affiliates. --> +<!-- Copyright (c) 2020, 2024, Oracle and/or its affiliates. --> <!-- Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. --> <results md5_sum="8ae88f8847e373ca6cc44516717e9e07"> <generated_date in_epoch_ms="1606849997000">2020-12-01 19:13:17</generated_date> + <patch has_prereqs="n" has_postreqs="n" is_system_patch="n"> + <bug> + <number>28186730</number> + <abstract><![CDATA[OPATCH 13.9.4.2.6 FOR EM 13.4, FMW/WLS 12.2.1.3.0, 12.2.1.4.0 AND 14.1.1.0.0]]></abstract> + </bug> + <name>28186730</name> + <type>Patch</type> + <status>Available</status> + <access id="m">Open access</access> + <url> + <patch_readme host="https://updates.oracle.com"><![CDATA[/Orion/Services/download?type=readme&aru=23901536]]></patch_readme> + <patch_details><![CDATA[/download/28186730.html]]></patch_details> + </url> + <request_id>23901536</request_id> + <urm_components> + <qparts ctype_id="201"> + <qpart cid="468882" version="Q12753"><![CDATA[Oracle Global Lifecycle Management OPatch]]></qpart> + </qparts> + <urm_releases ctype_id="5"> + <urm_release cid="1007556" version="13.9.4.2.6"><![CDATA[OPatch]]></urm_release> + </urm_releases> + </urm_components> + <product id="31944" bugdb_id="12753"><![CDATA[Oracle Global Lifecycle Management OPatch]]></product> + <release id="600000000159823" platform_patch_not_required="Y" cc="Y"><![CDATA[OPatch 13.9.4.2.6]]></release> + <platform id="2000" bugdb_id="289"><![CDATA[Generic Platform]]></platform> + <language id="0" iso_code="EN"><![CDATA[American English]]></language> + <translations_available>No</translations_available> + <classification id="174">General</classification> + <patch_classification id="174">General</patch_classification> + <support_level id="G">General Support</support_level> + <entitlements> + <entitlement code="SW"/> + </entitlements> + <size>45855234</size> + <files> + <file> + <name>p28186730_139425_Generic.zip</name> + <size>45855234</size> + <download_url host="https://updates.oracle.com"><![CDATA[/Orion/Services/download/p28186730_139425_Generic.zip?aru=23901536&patch_file=p28186730_139426_Generic.zip]]></download_url> + <digest type="SHA-256">8BFC99E439DA1D1663F88D6859EC19E9926A473C96B95889ABE5F45C055E1BB3</digest> + <digest type="SHA-1">41E3536305E6A71776717D700FA41B1A1AB0A493</digest> + </file> + </files> + <updated_date in_epoch_ms="1604594811000">2020-11-05 16:46:51</updated_date> + <released_date in_epoch_ms="1604592571000">2020-11-05 16:09:31</released_date> + </patch> <patch has_prereqs="n" has_postreqs="n" is_system_patch="n"> <bug> <number>28186730</number> diff --git a/installer/pom.xml b/installer/pom.xml index 4012f0c0f..731dda304 100644 --- a/installer/pom.xml +++ b/installer/pom.xml @@ -13,7 +13,7 @@ <parent> <artifactId>imagetool-parent</artifactId> <groupId>com.oracle.weblogic.lifecycle.imagetool</groupId> - <version>1.12.2</version> + <version>1.13.0</version> <relativePath>../pom.xml</relativePath> </parent> diff --git a/pom.xml b/pom.xml index 465a4ddfe..9252d767f 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.oracle.weblogic.lifecycle.imagetool</groupId> <artifactId>imagetool-parent</artifactId> - <version>1.12.2</version> + <version>1.13.0</version> <packaging>pom</packaging> <name>WebLogic Image Tool</name> @@ -67,7 +67,7 @@ <dependency> <groupId>info.picocli</groupId> <artifactId>picocli</artifactId> - <version>4.7.4</version> + <version>4.7.5</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> @@ -242,7 +242,7 @@ <dependency> <groupId>com.puppycrawl.tools</groupId> <artifactId>checkstyle</artifactId> - <version>10.12.4</version> + <version>10.12.7</version> </dependency> </dependencies> </plugin> @@ -261,7 +261,7 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.10</version> + <version>0.8.11</version> <executions> <execution> <id>prepare-agent</id> @@ -281,7 +281,7 @@ <plugin> <groupId>org.sonarsource.scanner.maven</groupId> <artifactId>sonar-maven-plugin</artifactId> - <version>3.9.1.2184</version> + <version>3.10.0.2594</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> diff --git a/tests/pom.xml b/tests/pom.xml index 22799ec7b..fa21946fb 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ <parent> <artifactId>imagetool-parent</artifactId> <groupId>com.oracle.weblogic.lifecycle.imagetool</groupId> - <version>1.12.2</version> + <version>1.13.0</version> <relativePath>../pom.xml</relativePath> </parent>