Skip to content

Commit d7dd80b

Browse files
authored
Auto-detect new OPatch releases during image build (#144)
* consolidate patch download logic so it can be overridden by Opatch patch logic * auto-detect newer versions of OPatch from ARU * update patch version before updating cache with newly downloaded patches * do not accept OPatch patch as a --patch
1 parent 7c70012 commit d7dd80b

File tree

10 files changed

+490
-405
lines changed

10 files changed

+490
-405
lines changed

imagetool/src/main/java/com/oracle/weblogic/imagetool/api/model/CachedFile.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.nio.file.Files;
1010
import java.nio.file.Path;
1111
import java.nio.file.Paths;
12+
import java.util.Objects;
1213

1314
import com.oracle.weblogic.imagetool.cachestore.CacheStore;
1415
import com.oracle.weblogic.imagetool.installer.InstallerType;
@@ -23,7 +24,8 @@ public class CachedFile {
2324

2425
private static final LoggingFacade logger = LoggingFactory.getLogger(CachedFile.class);
2526

26-
private String key;
27+
private String id;
28+
private String version;
2729

2830
/**
2931
* Represents a locally cached file.
@@ -32,7 +34,9 @@ public class CachedFile {
3234
* @param version version number for the patch or installer.
3335
*/
3436
public CachedFile(String id, String version) {
35-
key = generateKey(id, version);
37+
Objects.requireNonNull(id, "key for the cached file cannot be null");
38+
this.id = id;
39+
this.version = version;
3640
}
3741

3842
/**
@@ -49,24 +53,26 @@ public static boolean isFileOnDisk(String filePath) {
4953
return filePath != null && Files.isRegularFile(Paths.get(filePath));
5054
}
5155

52-
private String generateKey(String id, String version) {
53-
54-
logger.entering(id, version);
55-
String mykey = id;
56-
if (id == null) { // should never happens
57-
mykey = id + CacheStore.CACHE_KEY_SEPARATOR + version;
58-
} else if (id.indexOf('_') < 0) {
59-
if (version != null) {
60-
mykey = mykey + CacheStore.CACHE_KEY_SEPARATOR + version;
61-
}
56+
/**
57+
* Get the key for this cache entry.
58+
* If the ID that was used to create this CachedFile object contains the separator (underscore),
59+
* then the key is the same as the ID. Otherwise, the key is the ID plus version, like ID + "_" + version.
60+
* @return the key to use for this cache entry, like xxxx_yyyy.
61+
*/
62+
public String getKey() {
63+
if (id.contains(CacheStore.CACHE_KEY_SEPARATOR)) {
64+
return id;
65+
} else {
66+
return id + CacheStore.CACHE_KEY_SEPARATOR + getVersion();
6267
}
63-
64-
logger.exiting(mykey);
65-
return mykey;
6668
}
6769

68-
public String getKey() {
69-
return key;
70+
/**
71+
* Get the version number for this cache entry/file.
72+
* @return the string version of this cached file.
73+
*/
74+
public String getVersion() {
75+
return version;
7076
}
7177

7278
/**

imagetool/src/main/java/com/oracle/weblogic/imagetool/cachestore/CachedPatchFile.java

Lines changed: 0 additions & 83 deletions
This file was deleted.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) 2020, Oracle Corporation and/or its affiliates.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
4+
package com.oracle.weblogic.imagetool.cachestore;
5+
6+
import java.io.FileNotFoundException;
7+
import java.io.IOException;
8+
import java.util.Set;
9+
import javax.xml.xpath.XPathExpressionException;
10+
11+
import com.oracle.weblogic.imagetool.logging.LoggingFacade;
12+
import com.oracle.weblogic.imagetool.logging.LoggingFactory;
13+
import com.oracle.weblogic.imagetool.util.Utils;
14+
import com.oracle.weblogic.imagetool.util.XPathUtil;
15+
16+
public class OPatchFile extends PatchFile {
17+
18+
private static final LoggingFacade logger = LoggingFactory.getLogger(OPatchFile.class);
19+
20+
public static final String DEFAULT_BUG_NUM = "28186730";
21+
22+
/**
23+
* Create an abstract file to hold the metadata for a patch file.
24+
* Default patch number for OPatch is 28186730.
25+
* Default version for OPatch is 13.9.4.0.0.
26+
*
27+
* @param patchId the ID of the patch
28+
* @param userId the username to use for retrieving the patch
29+
* @param password the password to use with the userId to retrieve the patch
30+
*/
31+
public OPatchFile(String patchId, String userId, String password, CacheStore cache) {
32+
super(getPatchId(patchId), latestVersion(cache, patchId, userId, password), userId, password);
33+
}
34+
35+
private static String getPatchId(String patchId) {
36+
if (patchId == null) {
37+
return DEFAULT_BUG_NUM;
38+
} else {
39+
return patchId;
40+
}
41+
}
42+
43+
/**
44+
* If a version is not part of the patchId, search the cache for the latest version of the OPatch patch.
45+
* If the provided patchId is not null (not default), just use the default version number.
46+
*
47+
* @param cache cache store to search
48+
* @param userId user credential
49+
* @param password user credential
50+
* @return the latest in the cache or the default version number
51+
*/
52+
private static String latestVersion(CacheStore cache, String patchId, String userId, String password) {
53+
String latestVersion = "0.0.0.0.0";
54+
// if patch version was not provided, and user/pass was not supplied, find the newest version in cache
55+
if (userId == null && password == null) {
56+
Set<String> keys = cache.getCacheItems().keySet();
57+
for (String key : keys) {
58+
if (key.startsWith(getPatchId(patchId))) {
59+
logger.fine("found OPatch entry in cache {0}", key);
60+
int split = key.indexOf('_');
61+
if (split < 0) {
62+
continue;
63+
}
64+
String cacheVersion = key.substring(split + 1);
65+
if (Utils.compareVersions(latestVersion, cacheVersion) < 0) {
66+
logger.fine("using cache {0} as newer OPatch version instead of {1}", key, latestVersion);
67+
latestVersion = cacheVersion;
68+
}
69+
}
70+
}
71+
72+
}
73+
return latestVersion;
74+
}
75+
76+
@Override
77+
public String resolve(CacheStore cacheStore) throws IOException {
78+
if (needAruInfo()) {
79+
initPatchInfo();
80+
}
81+
try {
82+
return super.resolve(cacheStore);
83+
} catch (FileNotFoundException fnfe) {
84+
throw new FileNotFoundException(Utils.getMessage("IMG-0062"));
85+
}
86+
}
87+
88+
@Override
89+
void confirmUniquePatchSelection() throws IOException {
90+
// if the user did not provide the patch version on the command line, use the latest version from ARU
91+
if (!isPatchVersionProvided()) {
92+
// grab the latest version for OPatch from ARU
93+
try {
94+
String latestVersion = XPathUtil.applyXPathReturnString(getAruInfo(),
95+
"string(/results/patch[access = 'Open access']/release/@name)");
96+
setPatchVersion(latestVersion);
97+
logger.fine("From ARU, setting OPatch patch version to {0}", latestVersion);
98+
} catch (XPathExpressionException xe) {
99+
throw new IOException(xe.getMessage());
100+
}
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)