Skip to content

fixing PSU parsing to properly handle 12.2.1.3 PSUs #1310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 126 additions & 25 deletions core/src/main/java/oracle/weblogic/deploy/util/XPathUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
*/
package oracle.weblogic.deploy.util;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
Expand All @@ -15,22 +26,26 @@
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

import oracle.weblogic.deploy.logging.PlatformLogger;
import oracle.weblogic.deploy.logging.WLSDeployLogFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/*
* Parse the xml file at the designated location for the PSU value
*/
public class XPathUtil {
private static final PlatformLogger LOGGER = WLSDeployLogFactory.getLogger("wlsdeploy.util");
private static final String PSU_DESCRIPTION_REGEX_OLD =
"^WebLogic Server (\\d+(\\.\\d+){3,5}) PSU Patch.*$";
private static final String PSU_DESCRIPTION_REGEX_NEW =
"^WLS PATCH SET UPDATE (\\d+(\\.\\d+){3,5})(\\(ID:(\\d+)\\.\\d+\\))?$";
private static final Pattern PSU_DESCRIPTION_PATTERN_OLD = Pattern.compile(PSU_DESCRIPTION_REGEX_OLD);
private static final Pattern PSU_DESCRIPTION_PATTERN_NEW = Pattern.compile(PSU_DESCRIPTION_REGEX_NEW);

String oracleHome;
String patchesHome;
public XPathUtil(String oracleHome){
Expand All @@ -52,8 +67,18 @@ private static synchronized XPathFactory factory() {
}

/*
* Get the PSU if one exists at the inventory/patches files. Look at the description
* for the PSU wording.
* Get the PSU if one exists at the inventory/patches files (only works for WLS installations using OPatch).
* Look at the description for the PSU wording. There are three known formats:
*
* - WLS PATCH SET UPDATE <version>.<PSU>
* - WLS PATCH SET UPDATE <version>.0(ID:<PSU>.<number>)
* - WebLogic Server <version>.<PSU> PSU Patch for BUG<number> <full date and time>
*
* The second format contains the PSU number in the first part of the ID. In at least one
* case, the PSU number has a 4 digit year so the extractPsu() method is using this methodology
* to compute the PSU in this case.
*
* The third format was used for early 12.1.2/12.1.3 PSUs.
*/
public String getPSU() {
// find the names in the directory first
Expand All @@ -63,29 +88,105 @@ public String getPSU() {
}
List<String> patchFiles = findPatchFiles();
List<String> list = new ArrayList<>();
for (String patch_file : patchFiles){
Document doc = readXmlFile(patch_file);
for (String patchFile : patchFiles){
Document doc = readXmlFile(patchFile);
String descrip = description(doc, "//@description");
LOGGER.fine("Description {0}", descrip);
if (descrip != null && descrip.startsWith("WLS PATCH SET UPDATE")) {
String psu = extractPsu(descrip);
list.add(psu);
Collections.sort(list);
return list.get(list.size() -1);
if (!StringUtils.isEmpty(descrip)) {
String psu = null;
Matcher matcher = PSU_DESCRIPTION_PATTERN_NEW.matcher(descrip);
if (matcher.matches()) {
psu = extractNewPsu(matcher);
} else {
matcher = PSU_DESCRIPTION_PATTERN_OLD.matcher(descrip);
if (matcher.matches()) {
psu = extractOldPsu(matcher);
}
}

if (psu != null) {
list.add(psu);
}
}
}
if (!list.isEmpty()) {
Collections.sort(list);
return list.get(list.size() - 1);
}
return null;
}

public String extractPsu(String descrip) {
int idx = descrip.lastIndexOf('.') + 1;
int endIdx = descrip.length() - 1;
if (descrip.charAt(endIdx) == ')') {
endIdx--;
// Only for unit testing
String extractNewPsu(String description) {
String psu = null;
if (description != null) {
Matcher matcher = PSU_DESCRIPTION_PATTERN_NEW.matcher(description);
if (matcher.matches()) {
psu = extractNewPsu(matcher);
}
}
return psu;
}

private String extractNewPsu(Matcher matcher) {
LOGGER.entering(matcher.group(0));

String psu = null;
int groupCount = matcher.groupCount();
if (groupCount == 4) {
String idGroup = matcher.group(4);
if (idGroup == null) {
psu = matcher.group(2).substring(1);
} else {
switch (idGroup.length()) {
case 6:
psu = idGroup;
break;

// PSU 12.2.1.3.0.190522 has the ID 20190522 so parse off the extra digits...
case 8:
psu = idGroup.substring(2);
break;

default:
LOGGER.warning("WLSDPLY-01052", idGroup, idGroup.length(), matcher.group(0));
break;
}
}
} else {
LOGGER.warning("WLSDPLY-01051", groupCount, matcher.group(0));
}

LOGGER.exiting(psu);
return psu;
}

// Only for unit testing
String extractOldPsu(String description) {
String psu = null;
if (description != null) {
Matcher matcher = PSU_DESCRIPTION_PATTERN_OLD.matcher(description);
if (matcher.matches()) {
psu = extractOldPsu(matcher);
}
}
return descrip.substring(idx, endIdx+1);
return psu;
}

private String extractOldPsu(Matcher matcher) {
LOGGER.entering(matcher.group(0));

String psu = null;
int groupCount = matcher.groupCount();
if (groupCount == 2) {
psu = matcher.group(2).substring(1);
} else {
LOGGER.warning("WLSDPLY-01051", groupCount, matcher.group(0));
}

LOGGER.exiting(psu);
return psu;
}

/**
* Locate the patch files in the Oracle home
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ WLSDPLY-01000=Password was truncated to {0} characters

# oracle.weblogic.deploy.util.XPathUtils.java
WLSDPLY-01050=WebLogic version for aliases is {0}
WLSDPLY-01051=WebLogic PSU description has an unexpected number of matching groups {0}: {1}
WLSDPLY-01052=WebLogic PSU description is an exception but the PSU number {0} length {1} was unexpected: {2}

# oracle.weblogic.deploy.util.FileUtils.java
WLSDPLY-01100=Failed to get the canonical file for {0} so falling back to absolute file instead: {1}
Expand Down
42 changes: 34 additions & 8 deletions core/src/test/java/oracle/weblogic/deploy/util/XPathUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,46 @@
public class XPathUtilTest {

@Test
void testPSUWithParen() {
void testNewPSUExceptionWith8Digits() {
XPathUtil util = new XPathUtil();
String tester = new String(".2145)");
String expected = new String("2145");
String actual = util.extractPsu(tester);
String tester = new String("WLS PATCH SET UPDATE 12.2.1.3.0(ID:20190522.070630)");
String expected = new String("190522");
String actual = util.extractNewPsu(tester);
assertEquals(expected, actual);
}

@Test
void testPSU() {
void testNewPSUExceptionWith6Digits() {
XPathUtil util = new XPathUtil();
String tester = new String(".2145");
String expected = new String("2145");
String actual = util.extractPsu(tester);
String tester = new String("WLS PATCH SET UPDATE 12.2.1.3.0(ID:191217.1425)");
String expected = new String("191217");
String actual = util.extractNewPsu(tester);
assertEquals(expected, actual);
}

void testNewPSUExceptionWithUnknownNumberOfDigits() {
XPathUtil util = new XPathUtil();
String tester = new String("WLS PATCH SET UPDATE 12.2.1.3.0(ID:12345.6789)");
String expected = null;
String actual = util.extractNewPsu(tester);
assertEquals(expected, actual);
}

@Test
void testNewPSU() {
XPathUtil util = new XPathUtil();
String tester = new String("WLS PATCH SET UPDATE 12.2.1.4.220329");
String expected = new String("220329");
String actual = util.extractNewPsu(tester);
assertEquals(expected, actual);
}

@Test
void testOldPSU() {
XPathUtil util = new XPathUtil();
String tester = new String("WebLogic Server 12.1.3.0.2 PSU Patch for BUG19637454 THU NOV 27 10:54:42 IST 2014");
String expected = new String("2");
String actual = util.extractOldPsu(tester);
assertEquals(expected, actual);
}
}