Skip to content

Commit 5fe83f8

Browse files
committed
Merge branch 'filter-for-arm-patches' into 'main'
Allow architecture specific patches to be selected and stored See merge request weblogic-cloud/weblogic-image-tool!485
2 parents 324a049 + ca44d80 commit 5fe83f8

27 files changed

+459
-322
lines changed

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

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
import java.nio.file.Files;
1010
import java.nio.file.Path;
1111
import java.nio.file.Paths;
12+
import java.util.ArrayList;
13+
import java.util.List;
1214
import java.util.Objects;
1315

1416
import com.oracle.weblogic.imagetool.cachestore.CacheStore;
1517
import com.oracle.weblogic.imagetool.installer.InstallerType;
1618
import com.oracle.weblogic.imagetool.logging.LoggingFacade;
1719
import com.oracle.weblogic.imagetool.logging.LoggingFactory;
18-
import com.oracle.weblogic.imagetool.util.BuildPlatform;
20+
import com.oracle.weblogic.imagetool.util.Architecture;
1921
import com.oracle.weblogic.imagetool.util.Utils;
2022

2123
/**
@@ -27,50 +29,40 @@ public class CachedFile {
2729

2830
private final String id;
2931
private final String version;
30-
private final String architecture;
32+
private final Architecture architecture;
3133

3234
/**
3335
* Represents a locally cached file.
3436
*
35-
* @param id cache ID (like installer type or patchId)
36-
* @param version version number for the patch or installer.
37-
* @param architecture the system architecture that this file/installer is applicable
37+
* @param id cache ID (like installer type or patchId)
38+
* @param version version number for the patch or installer.
39+
* @param target the system architecture that this file/installer is applicable
3840
*/
39-
public CachedFile(String id, String version, String architecture) {
41+
public CachedFile(String id, String version, Architecture target) {
4042
Objects.requireNonNull(id, "key for the cached file cannot be null");
41-
logger.entering(id, version, architecture);
43+
logger.entering(id, version, target);
4244
this.id = id;
4345
this.version = version;
44-
this.architecture = architecture;
46+
this.architecture = target;
4547
logger.exiting();
4648
}
4749

4850
/**
4951
* Represents a locally cached file.
5052
*
51-
* @param id cache ID (like installer type or patchId)
52-
* @param version version number for the patch or installer.
53+
* @param id cache ID (like installer type)
54+
* @param version version number for the patch or installer.
55+
* @param target the system architecture that this file/installer is applicable
5356
*/
54-
public CachedFile(String id, String version) {
55-
this(id, version, null);
57+
public CachedFile(InstallerType id, String version, Architecture target) {
58+
this(id.toString(), version, target);
5659
}
5760

5861
/**
5962
* Represents a locally cached file.
6063
*
61-
* @param id cache ID (like installer type)
62-
* @param version version number for the patch or installer.
63-
* @param architecture the system architecture that this file/installer is applicable
64-
*/
65-
public CachedFile(InstallerType id, String version, String architecture) {
66-
this(id.toString(), version, architecture);
67-
}
68-
69-
/**
70-
* Represents a locally cached file.
71-
*
72-
* @param id cache ID (like installer type)
73-
* @param version version number for the patch or installer.
64+
* @param id cache ID (like installer type)
65+
* @param version version number for the patch or installer.
7466
*/
7567
public CachedFile(InstallerType id, String version) {
7668
this(id.toString(), version, null);
@@ -87,10 +79,14 @@ public static boolean isFileOnDisk(String filePath) {
8779
* @return the key to use for this cache entry, like xxxx_yyyy.
8880
*/
8981
public String getKey() {
90-
return getCacheKey(architecture);
82+
if (architecture == null) {
83+
return getCacheKey(null);
84+
} else {
85+
return getCacheKey(architecture.toString());
86+
}
9187
}
9288

93-
private String getCacheKey(String architecture) {
89+
private String getCacheKey(String arch) {
9490
if (id.contains(CacheStore.CACHE_KEY_SEPARATOR)) {
9591
return id;
9692
}
@@ -99,13 +95,19 @@ private String getCacheKey(String architecture) {
9995
key.append(id);
10096
key.append(CacheStore.CACHE_KEY_SEPARATOR);
10197
key.append(version);
102-
if (architecture != null) {
98+
if (arch != null) {
10399
key.append(CacheStore.CACHE_KEY_SEPARATOR);
104-
key.append(architecture);
100+
key.append(arch);
105101
}
106102
return key.toString();
107103
}
108104

105+
private List<String> getPossibleKeys(Architecture architecture) {
106+
ArrayList<String> result = new ArrayList<>();
107+
architecture.getAcceptableNames().forEach(name -> result.add(getCacheKey(name)));
108+
return result;
109+
}
110+
109111
/**
110112
* Get the version number for this cache entry/file.
111113
* @return the string version of this cached file.
@@ -118,7 +120,7 @@ public String getVersion() {
118120
* Get the system architecture name for this cache entry/file.
119121
* @return the system architecture name applicable fo this cached file.
120122
*/
121-
public String getArchitecture() {
123+
public Architecture getArchitecture() {
122124
return architecture;
123125
}
124126

@@ -136,30 +138,29 @@ public String getArchitecture() {
136138
*/
137139
public String resolve(CacheStore cacheStore) throws IOException {
138140
// check entry exists in cache
139-
String key = getKey();
140-
logger.entering(key);
141-
String filePath = cacheStore.getValueFromCache(key);
142-
if (filePath == null) {
143-
// The KEY for this CachedFile was not found in the local cache.
144-
logger.fine("Unable to find cache entry for {0}", key);
145-
String alternateKey;
146-
if (getArchitecture() == null) {
147-
// The user did not specify an architecture in the KEY and that key was not found in the cache.
148-
// Try adding the local architecture to the key, and look for that entry.
149-
alternateKey = getCacheKey(BuildPlatform.getPlatformName());
150-
logger.fine("Trying local architecture: {0}", alternateKey);
151-
} else {
152-
// The user specified an architecture in the KEY, but that key was not found.
153-
// Try removing the architecture from the key, and look for that entry.
154-
alternateKey = getCacheKey(null);
155-
logger.fine("Trying no-arch/generic architecture: {0}", alternateKey);
141+
logger.entering();
142+
String filePath = null;
143+
List<String> keySearchOrder = new ArrayList<>();
144+
if (getArchitecture() == null) {
145+
// architecture was not specified, search for cache key with no arch first, then look for local arch
146+
keySearchOrder.add(getCacheKey(null));
147+
keySearchOrder.addAll(getPossibleKeys(Architecture.getLocalArchitecture()));
148+
} else {
149+
// architecture was specified, search for cache key with arch first, then look for no arch key
150+
keySearchOrder.addAll(getPossibleKeys(getArchitecture()));
151+
keySearchOrder.add(getCacheKey(null));
152+
}
153+
for (String key: keySearchOrder) {
154+
logger.finer("Trying cache key {0}", key);
155+
filePath = cacheStore.getValueFromCache(key);
156+
if (filePath != null) {
157+
logger.finer("Found cache key {0}", key);
158+
break;
156159
}
157-
// second attempt to find a reasonable cache entry
158-
filePath = cacheStore.getValueFromCache(alternateKey);
159160
}
160161

161162
if (!isFileOnDisk(filePath)) {
162-
throw new FileNotFoundException(Utils.getMessage("IMG-0011", key));
163+
throw new FileNotFoundException(Utils.getMessage("IMG-0011", getKey()));
163164
}
164165

165166
logger.exiting(filePath);

imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class AruPatch {
3030
private String product;
3131
private String release;
3232
private String releaseName;
33+
private int platform;
3334
private String psuBundle;
3435
private String downloadHost;
3536
private String downloadPath;
@@ -95,6 +96,15 @@ public AruPatch releaseName(String value) {
9596
return this;
9697
}
9798

99+
public Integer platform() {
100+
return platform;
101+
}
102+
103+
public AruPatch platform(String value) {
104+
platform = Integer.parseInt(value);
105+
return this;
106+
}
107+
98108
public String psuBundle() {
99109
return psuBundle;
100110
}
@@ -167,9 +177,9 @@ public boolean isCoherenceFeaturePack() {
167177
* @throws XPathExpressionException if the document is not the expected format from ARU
168178
*/
169179
public static Stream<AruPatch> getPatches(Document patchList) throws XPathExpressionException {
170-
// create list of all patches that apply to the Linux platform
180+
// create list of all patches that apply (platforms 2000=generic, 226=amd64, 541=arm64)
171181
NodeList nodeList = XPathUtil.nodelist(patchList,
172-
"/results/patch[./platform[@id='2000' or @id='226']]");
182+
"/results/patch[./platform[@id='2000' or @id='226' or @id='541']]");
173183
Stream.Builder<AruPatch> result = Stream.builder();
174184
for (int i = 0; i < nodeList.getLength(); i++) {
175185
if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
@@ -183,7 +193,8 @@ public static Stream<AruPatch> getPatches(Document patchList) throws XPathExpres
183193
.psuBundle(XPathUtil.string(nodeList.item(i), "./psu_bundle"))
184194
.access(XPathUtil.string(nodeList.item(i), "./access"))
185195
.downloadHost(XPathUtil.string(nodeList.item(i), "./files/file/download_url/@host"))
186-
.downloadPath(XPathUtil.string(nodeList.item(i), "./files/file/download_url/text()"));
196+
.downloadPath(XPathUtil.string(nodeList.item(i), "./files/file/download_url/text()"))
197+
.platform(XPathUtil.string(nodeList.item(i), "./platform/@id"));
187198

188199
int index = patch.downloadPath().indexOf("patch_file=");
189200
if (index < 0) {
@@ -197,6 +208,7 @@ public static Stream<AruPatch> getPatches(Document patchList) throws XPathExpres
197208
+ " desc:" + patch.description()
198209
+ " rel:" + patch.release()
199210
+ " product:" + patch.product()
211+
+ " platform:" + patch.platform()
200212
+ " relName:" + patch.releaseName()
201213
+ " psu:" + patch.psuBundle()
202214
+ " url:" + patch.downloadUrl());
@@ -220,16 +232,11 @@ public static Stream<AruPatch> getPatches(Document patchList) throws XPathExpres
220232
*/
221233
public static AruPatch selectPatch(List<AruPatch> patches, String providedVersion, String psuVersion,
222234
String installerVersion)
223-
throws VersionNotFoundException, MultiplePatchVersionsException {
235+
throws VersionNotFoundException, PatchVersionException {
224236

225237
logger.entering(patches, providedVersion, psuVersion, installerVersion);
226238
AruPatch selected = null;
227239

228-
if (patches.size() < 2) {
229-
// 0 or 1 patch, fill in a patch version and just return what have
230-
return selectPatchOffline(patches, providedVersion, psuVersion, installerVersion);
231-
}
232-
233240
Map<String, AruPatch> patchMap = patches.stream().collect(Collectors
234241
.toMap(AruPatch::version, aruPatch -> aruPatch));
235242
// select the correct patch version (priority order: user provided version, PSU version, GA installer version)
@@ -249,40 +256,22 @@ public static AruPatch selectPatch(List<AruPatch> patches, String providedVersio
249256

250257
logger.exiting(selected);
251258
if (selected == null) {
252-
throw logger.throwing(new MultiplePatchVersionsException(patches.get(0).patchId(), patches));
259+
throw logger.throwing(new PatchVersionException(patches.get(0).patchId(), patches));
253260
} else {
254261
logger.info("IMG-0099", selected.patchId(), selected.version(), selected.description());
255262
return selected;
256263
}
257264
}
258265

259-
private static AruPatch selectPatchOffline(List<AruPatch> patches, String providedVersion, String psuVersion,
260-
String installerVersion) throws VersionNotFoundException {
261-
AruPatch result = null;
262-
263-
if (patches.isEmpty()) {
264-
logger.fine("Patches list is empty");
265-
} else if (patches.size() == 1) {
266-
result = patches.get(0);
267-
// if the version is filled in, we are working online and there is nothing more to do.
268-
if (result.version() == null) {
269-
// no version means the patch is from the cache. Set the version as best we can.
270-
// TODO: this could be improved if the cache was improved to store patch version.
271-
if (providedVersion != null) {
272-
result.version(providedVersion);
273-
} else if (psuVersion != null) {
274-
result.version(psuVersion);
275-
} else {
276-
result.version(installerVersion);
277-
}
278-
} else if (providedVersion != null && !result.version().equals(providedVersion)) {
279-
throw logger.throwing(new VersionNotFoundException(result.patchId(), providedVersion, patches));
280-
} else {
281-
logger.info("IMG-0099", result.patchId(), result.version(), result.description());
282-
}
283-
}
284-
logger.exiting(result);
285-
return result;
266+
/**
267+
* Return true if this patch is applicable to the target platform.
268+
* Patch platform 2000 is generic and applicable to all platforms.
269+
* @param aruPlatform the target ARU platform to check.
270+
* @return true if this patch is applicable to the provided platform.
271+
*/
272+
public boolean isApplicableToTarget(int aruPlatform) {
273+
// if this patch is for platform 2000, always return true, else return true if platforms are equal.
274+
return platform == 2000 || platform == aruPlatform;
286275
}
287276

288277
@Override

0 commit comments

Comments
 (0)