Skip to content

Commit

Permalink
Fixed resource validation + partial test coverage
Browse files Browse the repository at this point in the history
Signed-off-by: David Matějček <david.matejcek@omnifish.ee>
  • Loading branch information
dmatej committed Mar 19, 2023
1 parent 96e9429 commit 56a6b13
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 169 deletions.
Expand Up @@ -21,7 +21,6 @@
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.ApplicationClientDescriptor;
import com.sun.enterprise.deployment.BundleDescriptor;
import com.sun.enterprise.deployment.CommonResourceValidator;
import com.sun.enterprise.deployment.ConnectorDescriptor;
import com.sun.enterprise.deployment.EjbBundleDescriptor;
import com.sun.enterprise.deployment.EjbDescriptor;
Expand All @@ -36,6 +35,7 @@
import com.sun.enterprise.deployment.WebBundleDescriptor;
import com.sun.enterprise.deployment.types.EjbReference;
import com.sun.enterprise.deployment.types.MessageDestinationReferencer;
import com.sun.enterprise.deployment.util.CommonResourceValidator.DuplicitDescriptor;

import java.lang.System.Logger;
import java.lang.System.Logger.Level;
Expand Down Expand Up @@ -134,8 +134,7 @@ public void accept(BundleDescriptor descriptor) {
accept((Application) descriptor);

if (!validateResourceDescriptor()) {
LOG.log(Level.ERROR, DOLUtils.APPLICATION_VALIDATION_FAILS, application.getAppName(), inValidJndiName);
throw new IllegalStateException(
throw new IllegalArgumentException(
MessageFormat.format("Application validation fails for given application {0} for jndi-name {1}",
application.getAppName(), inValidJndiName));
}
Expand Down Expand Up @@ -515,8 +514,7 @@ private boolean findConflictingDescriptors(Set<ResourceDescriptor> descriptors,
* @return true if there is another descriptor under the same name.
*/
private boolean isConflictingDescriptor(SimpleJndiName name, ResourceDescriptor descriptor, String scope) {
// FIXME: lower level!
LOG.log(Level.INFO, "isConflictingDescriptor(name={0}, descriptor, scope={1})", name, scope);
LOG.log(Level.DEBUG, "isConflictingDescriptor(name={0}, descriptor, scope={1})", name, scope);
if (descriptor == null) {
return false;
}
Expand All @@ -528,9 +526,10 @@ private boolean isConflictingDescriptor(SimpleJndiName name, ResourceDescriptor
final ResourceDescriptor existingDescriptor = commonResourceValidator.getDescriptor();
if (descriptor.equals(existingDescriptor)) {
// Requires further processing based on scopes
commonResourceValidator.addScope(scope);
commonResourceValidator.addDuplicity(descriptor, scope);
return false;
}

// Same JNDI names, but different descriptors
LOG.log(Level.ERROR, DOLUtils.DUPLICATE_DESCRIPTOR, name);
allUniqueResource = false;
Expand All @@ -542,73 +541,71 @@ private boolean isConflictingDescriptor(SimpleJndiName name, ResourceDescriptor
* Compare descriptor at given scope is valid and unique.
*/
private boolean compareDescriptors() {

List<String> appLevelScopes = validNameSpaceDetails.get(APP_KEYS);
List<String> ebdLevelScopes = validNameSpaceDetails.get(EJBBUNDLE_KEYS);
for (Entry<SimpleJndiName, CommonResourceValidator> descriptor : allResourceDescriptors.entrySet()) {
CommonResourceValidator commonResourceValidator = descriptor.getValue();
List<String> scopes = commonResourceValidator.getScope();
SimpleJndiName jndiName = commonResourceValidator.getJndiName();
for (Entry<SimpleJndiName, CommonResourceValidator> entry : allResourceDescriptors.entrySet()) {
CommonResourceValidator validator = entry.getValue();
SimpleJndiName jndiName = validator.getJndiName();
List<DuplicitDescriptor> possibleConflicts = validator.getDescriptors();

if (jndiName.contains(JNDI_COMP)) {
for (String scope : scopes) {
for (DuplicitDescriptor candidate : possibleConflicts) {
for (String appLevelScope : appLevelScopes) {
if (scope.equals(appLevelScope)) {
if (candidate.scope.equals(appLevelScope)) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, DOLUtils.INVALID_JNDI_SCOPE, jndiName);
LOG.log(Level.ERROR, DOLUtils.INVALID_JNDI_SCOPE, candidate, jndiName);
return false;
}
}
for (String ebdLevelScope : ebdLevelScopes) {
if (scope.equals(ebdLevelScope)) {
if (candidate.scope.equals(ebdLevelScope)) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, DOLUtils.INVALID_JNDI_SCOPE, jndiName);
LOG.log(Level.ERROR, DOLUtils.INVALID_JNDI_SCOPE, candidate, jndiName);
return false;
}
}
}
}

if (jndiName.contains(JNDI_MODULE)) {
for (String scope : scopes) {
for (DuplicitDescriptor candidate : possibleConflicts) {
for (String appLevelScope : appLevelScopes) {
if (scope.equals(appLevelScope)) {
if (candidate.scope.equals(appLevelScope)) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, DOLUtils.INVALID_JNDI_SCOPE, jndiName);
LOG.log(Level.ERROR, DOLUtils.INVALID_JNDI_SCOPE, candidate, jndiName);
return false;
}
}
}
}

if (scopes.size() > 1) {
if (jndiName.contains(JNDI_COMP)) {
if (!compareVectorForComp(scopes, jndiName)) {
return false;
}
} else if (jndiName.contains(JNDI_MODULE)) {
if (!compareVectorForModule(scopes, jndiName)) {
return false;
}
} else if (jndiName.contains(JNDI_APP)) {
if (!compareVectorForApp(scopes, jndiName)) {
if (possibleConflicts.size() <= 1) {
continue;
}
if (jndiName.contains(JNDI_COMP)) {
if (!compareVectorForComp(possibleConflicts, jndiName)) {
return false;
}
} else if (jndiName.contains(JNDI_MODULE)) {
if (!compareVectorForModule(possibleConflicts, jndiName)) {
return false;
}
} else if (jndiName.contains(JNDI_APP)) {
if (!compareVectorForApp(possibleConflicts, jndiName)) {
return false;
}
} else {
try {
InitialContext ic = new InitialContext();
Object lookup = ic.lookup(jndiName.toString());
if (lookup != null) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, DOLUtils.JNDI_LOOKUP_FAILED, jndiName);
return false;
}
} else {
try {
InitialContext ic = new InitialContext();
Object lookup = ic.lookup(jndiName.toString());
if (lookup != null) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, DOLUtils.JNDI_LOOKUP_FAILED, jndiName);
return false;
}
} catch (NamingException e) {
/*
Do nothing, this is expected.
A failed lookup means there's no conflict with a resource defined on the server.
*/
}
} catch (NamingException e) {
// Do nothing, this is expected. Failed lookup means there's no conflict
// with a resource defined on the server.
}
}
}
Expand All @@ -618,20 +615,18 @@ private boolean compareDescriptors() {
/**
* Method to validate jndi name for app namespace
*/
private boolean compareVectorForApp(List<String> scopes, SimpleJndiName jndiName) {
for (int j = 0; j < scopes.size(); j++) {
String firstElement = scopes.get(j);
if (firstElement.contains("#")) {
firstElement = firstElement.substring(0, firstElement.indexOf("#"));
}
for (int i = j + 1; i < scopes.size(); i++) {
String otherElements = scopes.get(i);
if (otherElements.contains("#")) {
otherElements = otherElements.substring(0, otherElements.indexOf("#"));
}
if (firstElement.equals(otherElements)) {
private boolean compareVectorForApp(List<DuplicitDescriptor> possibleConflicts, SimpleJndiName jndiName) {
for (int j = 0; j < possibleConflicts.size(); j++) {
final DuplicitDescriptor candidate1 = possibleConflicts.get(j);
final String scope1 = getFirstScopeSegment(candidate1.scope);
for (int i = j + 1; i < possibleConflicts.size(); i++) {
final DuplicitDescriptor candidate2 = possibleConflicts.get(i);
final String scope2 = getFirstScopeSegment(candidate2.scope);
if (scope1.equals(scope2) && candidate1.descriptor != candidate2.descriptor) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, DOLUtils.INVALID_NAMESPACE, jndiName, application.getAppName());
LOG.log(Level.WARNING,
"JNDI name {0} is declared by multiple modules of the application {1}: {2}, {3}", jndiName,
application.getAppName(), candidate1.scope, candidate2.scope);
}
}
}
Expand All @@ -642,28 +637,18 @@ private boolean compareVectorForApp(List<String> scopes, SimpleJndiName jndiName
/**
* Method to validate jndi name for module namespace
*/
private boolean compareVectorForModule(List<String> scopes, SimpleJndiName jndiName) {
if (!compareVectorForApp(scopes, jndiName)) {
private boolean compareVectorForModule(List<DuplicitDescriptor> possibleConflicts, SimpleJndiName jndiName) {
if (!compareVectorForApp(possibleConflicts, jndiName)) {
return false;
}

for (int j = 0; j < scopes.size(); j++) {
String firstElement = scopes.get(0);
if (firstElement.contains("#")) {
firstElement = firstElement.substring(firstElement.indexOf("#") + 1, firstElement.length());
}
if (firstElement.contains("#")) {
firstElement = firstElement.substring(0, firstElement.indexOf("#"));
}
for (int i = j + 1; i < scopes.size(); i++) {
String otherElements = scopes.get(i);
if (otherElements.contains("#")) {
otherElements = otherElements.substring(otherElements.indexOf("#") + 1, otherElements.length());
}
if (otherElements.contains("#")) {
otherElements = otherElements.substring(0, otherElements.indexOf("#"));
}
if (firstElement.equals(otherElements)) {
for (int j = 0; j < possibleConflicts.size(); j++) {
DuplicitDescriptor candidate1 = possibleConflicts.get(j);
String scope1 = getFirstScopeSegment(removeFirstScopeSegment(candidate1.scope));
for (int i = j + 1; i < possibleConflicts.size(); i++) {
DuplicitDescriptor candidate2 = possibleConflicts.get(i);
String scope2 = getFirstScopeSegment(removeFirstScopeSegment(candidate1.scope));
if (scope1.equals(scope2) && candidate1.descriptor != candidate2.descriptor) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, INVALID_NAMESPACE, jndiName, application.getAppName());
}
Expand All @@ -676,28 +661,18 @@ private boolean compareVectorForModule(List<String> scopes, SimpleJndiName jndiN
/**
* Method to validate jndi name for comp namespace
*/
private boolean compareVectorForComp(List<String> scopes, SimpleJndiName jndiName) {
if (!compareVectorForModule(scopes, jndiName)) {
private boolean compareVectorForComp(List<DuplicitDescriptor> possibleConflicts, SimpleJndiName jndiName) {
if (!compareVectorForModule(possibleConflicts, jndiName)) {
return false;
}

for (int j = 0; j < scopes.size(); j++) {
String firstElement = scopes.get(0);
if (firstElement.contains("#")) {
firstElement = firstElement.substring(firstElement.lastIndexOf("#") + 1, firstElement.length());
}
if (firstElement.contains("#")) {
firstElement = firstElement.substring(firstElement.lastIndexOf("#") + 1, firstElement.length());
}
for (int i = j + 1; i < scopes.size(); i++) {
String otherElements = scopes.get(i);
if (otherElements.contains("#")) {
otherElements = otherElements.substring(otherElements.lastIndexOf("#") + 1, otherElements.length());
}
if (otherElements.contains("#")) {
otherElements = otherElements.substring(otherElements.lastIndexOf("#") + 1, otherElements.length());
}
if (firstElement.equals(otherElements)) {
for (int j = 0; j < possibleConflicts.size(); j++) {
DuplicitDescriptor candidate1 = possibleConflicts.get(j);
String scope1 = getLastScopeSegment(getLastScopeSegment(candidate1.scope));
for (int i = j + 1; i < possibleConflicts.size(); i++) {
DuplicitDescriptor candidate2 = possibleConflicts.get(i);
String scope2 = getLastScopeSegment(getLastScopeSegment(candidate2.scope));
if (scope1.equals(scope2) && candidate1.descriptor != candidate2.descriptor) {
inValidJndiName = jndiName;
LOG.log(Level.ERROR, INVALID_NAMESPACE, jndiName, application.getAppName());
return false;
Expand All @@ -706,4 +681,22 @@ private boolean compareVectorForComp(List<String> scopes, SimpleJndiName jndiNam
}
return true;
}


private String getFirstScopeSegment(String scope) {
final int index = scope.indexOf('#');
return index > 0 ? scope.substring(0, index) : scope;
}


private String removeFirstScopeSegment(String scope) {
final int index = scope.indexOf('#');
return index > 0 ? scope.substring(index + 1) : scope;
}


private String getLastScopeSegment(String scope) {
int index = scope.lastIndexOf('#') + 1;
return index > 0 ? scope.substring(index) : scope;
}
}
Expand Up @@ -15,7 +15,9 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package com.sun.enterprise.deployment;
package com.sun.enterprise.deployment.util;

import com.sun.enterprise.deployment.ResourceDescriptor;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -25,33 +27,53 @@

/**
* @author naman, date: 24/5/12
* @author David Matejcek 2023
*/
public class CommonResourceValidator {
class CommonResourceValidator {

private final ResourceDescriptor descriptor;
private final SimpleJndiName jndiName;
private final List<String> scope;
private final List<DuplicitDescriptor> descriptors;

public CommonResourceValidator(ResourceDescriptor descriptor, SimpleJndiName jndiName, String scope) {
CommonResourceValidator(ResourceDescriptor descriptor, SimpleJndiName jndiName, String scope) {
this.descriptor = descriptor;
this.jndiName = Objects.requireNonNull(jndiName, "jndiName");
this.scope = new ArrayList<>();
this.scope.add(scope);
this.descriptors = new ArrayList<>();
this.descriptors.add(new DuplicitDescriptor(descriptor, scope));
}

public ResourceDescriptor getDescriptor() {
ResourceDescriptor getDescriptor() {
return descriptor;
}

public SimpleJndiName getJndiName() {
SimpleJndiName getJndiName() {
return jndiName;
}

public List<String> getScope() {
return scope;
/**
* @return descriptors with the same JNDI name and their scopes
*/
List<DuplicitDescriptor> getDescriptors() {
return descriptors;
}

void addDuplicity(ResourceDescriptor duplicit, String scope) {
this.descriptors.add(new DuplicitDescriptor(duplicit, scope));
}

public void addScope(String scope) {
this.scope.add(scope);

static class DuplicitDescriptor {
public final ResourceDescriptor descriptor;
public final String scope;

private DuplicitDescriptor(ResourceDescriptor descriptor, String scope) {
this.descriptor = descriptor;
this.scope = scope;
}

@Override
public String toString() {
return scope;
}
}
}
Expand Up @@ -147,13 +147,6 @@ public class DOLUtils {
+ " Ensure that the SAX parser configuration is correct and the descriptor has right permissions.")
public static final String INVALILD_DESCRIPTOR_SHORT = "AS-DEPLOYMENT-00120";

@LogMessageInfo(
message = "DEP0001:Application validation fails for given application: {0}, and jndi-name: {1}",
level = "SEVERE",
cause = "A JNDI name used for a resource in the given app fails validation",
action = "This is an aggregated error. Have a look at previous log messages for more details about the errors")
public static final String APPLICATION_VALIDATION_FAILS = "enterprise.deployment.util.application.fail";

@LogMessageInfo(
message = "DEP0002:Duplicate descriptor found for given jndi-name: {0}",
level = "SEVERE",
Expand All @@ -179,7 +172,7 @@ public class DOLUtils {
public static final String INVALID_NAMESPACE = "enterprise.deployment.util.application.invalid.namespace";

@LogMessageInfo(
message = "DEP0005:Deployment failed due to the invalid scope defined for jndi-name: {0}",
message = "DEP0005:Deployment failed due to the invalid scope {0} defined for jndi-name: {1}",
level = "SEVERE",
cause = "Unknown",
action = "Unknown")
Expand Down

0 comments on commit 56a6b13

Please sign in to comment.