Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.openl.rules.maven.VerifyMojo Maven / Gradle / Ivy
package org.openl.rules.maven;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.maven.RepositoryUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.util.artifact.JavaScopes;
/**
* Verifies if resulted archive is compatible with the OpenL Tablets Rules Engine
*
* @author Vladyslav Pikus
* @since 5.24.0
*/
@Mojo(name = "verify", defaultPhase = LifecyclePhase.VERIFY, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class VerifyMojo extends BaseOpenLMojo {
/**
* Parameter to skip running OpenL Tablets verify goal if it set to 'true'.
*/
@Parameter(property = "skipTests")
private boolean skipTests;
/**
* Parameter to skip running OpenL Tablets verify goal if it set to 'true'.
*
* @deprecated for troubleshooting purposes
*/
@Parameter(property = "skipITs")
@Deprecated
private boolean skipITs;
@Parameter(defaultValue = "${project.build.directory}", required = true, readonly = true)
private File outputDirectory;
@Parameter(defaultValue = "${plugin}", readonly = true)
private PluginDescriptor plugin;
@Parameter(defaultValue = "${plugin.artifacts}", readonly = true, required = true)
private List pluginArtifacts;
@Parameter(defaultValue = "${session}", readonly = true)
private MavenSession mavenSession;
@Component
private RepositorySystem repositorySystem;
@Parameter(defaultValue = "${repositorySystemSession}", readonly = true, required = true)
private RepositorySystemSession session;
@Override
void execute(String sourcePath, boolean hasDependencies) throws Exception {
var pathDeployment = project.getAttachedArtifacts()
.stream()
.filter(artifact -> PackageMojo.DEPLOYMENT_CLASSIFIER.equals(artifact.getClassifier()))
.findFirst()
.orElseGet(project::getArtifact)
.getFile()
.getPath();
var openlJars = new HashMap();
// OpenL RuleServices Application dependencies
openlJars.putAll(getJars("org.openl.rules:org.openl.rules.ruleservice.ws"));
// Transitive dependencies required to be added to the same classpath of RuleServices
openlJars.putAll(getTransitiveDependencies());
// Dependencies from the plugin section
for (var dep : plugin.getPlugin().getDependencies()) {
openlJars.putAll(getJars(versionlessKey(dep.getGroupId(), dep.getArtifactId(), dep.getClassifier())));
}
// Remove log4j due LOG4J2-3657 and needeless to log to the file.
openlJars.remove("org.apache.logging.log4j:log4j-core");
openlJars.remove("org.apache.logging.log4j:log4j-slf4j2-impl");
var world = new ClassWorld();
var jettyClassLoader = world.newRealm("jetty");
// JettysourcePathsourcePath Server with annotations
for (var x : getJars("org.eclipse.jetty:jetty-annotations").values()) {
jettyClassLoader.addURL(x.toURI().toURL());
}
// Enable logging in the Jetty server via Maven logger API
jettyClassLoader.importFrom(plugin.getClassRealm(), "org.slf4j");
// Required to provide runner AppServer class
jettyClassLoader.addURL(plugin.getPluginArtifact().getFile().toURI().toURL());
// Instantiate and run Jetty server on clean classloader without Maven libraries
var oldClassloader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(jettyClassLoader);
var appClass = jettyClassLoader.loadClass("org.openl.rules.maven.AppServer");
var checkMethod = appClass.getDeclaredMethod("check", String.class, Collection.class, String.class);
checkMethod.invoke(null, pathDeployment, openlJars.values(), outputDirectory.getPath());
info(String.format("Verification is passed for '%s:%s' artifact.", project.getGroupId(), project.getArtifactId()));
} catch (Exception e) {
throw new MojoFailureException(String
.format("Verification is failed for '%s:%s' artifact.", project.getGroupId(), project.getArtifactId()), e);
} finally {
Thread.currentThread().setContextClassLoader(oldClassloader);
world.disposeRealm("jetty");
}
}
/**
* Gets path to the resolved jars, including transitive.
*
* @param artifactId - groupId:artifactId
* @return a set of downloaded jars
* @throws DependencyResolutionException
*/
private Map getJars(String artifactId) throws DependencyResolutionException {
// Find an artifact inside the openl-maven-plugin
var artifact = pluginArtifacts.stream()
.filter(x -> versionlessKey(x.getGroupId(), x.getArtifactId(), x.getClassifier()).equals(artifactId))
.map(RepositoryUtils::toArtifact)
.findFirst().get();
// Resolve transitive dependencies and get its jar files
var collectRequest = new CollectRequest();
collectRequest.setRoot(new Dependency(artifact, JavaScopes.RUNTIME));
var dependencyRequest = new DependencyRequest(collectRequest, null);
var openlDependencies = repositorySystem.resolveDependencies(session, dependencyRequest).getArtifactResults();
var result = new HashMap(openlDependencies.size());
for (var x : openlDependencies) {
var a = x.getArtifact();
result.put(versionlessKey(a.getGroupId(), a.getArtifactId(), a.getClassifier()), a.getFile());
}
return result;
}
private Map getTransitiveDependencies() {
Set pluginDependencies = plugin.getDependencies().stream()
.map(d -> versionlessKey(d.getGroupId(), d.getArtifactId(), null))
.collect(Collectors.toSet());
Set allowedDependencies = getAllowedDependencies();
return getDependentNonOpenLProjects().stream().filter(artifact -> {
if (isOpenLCoreDependency(artifact.getGroupId())) {
debug("SKIP : ", artifact);
return false;
}
return true;
}).filter(artifact -> {
List dependencyTrail = artifact.getDependencyTrail();
if (dependencyTrail.size() < 2) {
debug("SKIP : ", artifact, " (by dependency depth)");
return false; // skip, unexpected size of dependencies
}
if (skipOpenLCoreDependency(dependencyTrail)) {
debug("SKIP : ", artifact, " (transitive dependency from OpenL or SLF4j dependencies)");
return false;
}
return true;
}).filter(a -> !pluginDependencies.contains(versionlessKey(a.getGroupId(), a.getArtifactId(), a.getClassifier())))
.filter(artifact -> {
String tr = artifact.getDependencyTrail().get(1);
String key = tr.substring(0, tr.indexOf(':', tr.indexOf(':') + 1));
return allowedDependencies.contains(key);
}).collect(Collectors.toMap(d -> versionlessKey(d.getGroupId(), d.getArtifactId(), d.getClassifier()), Artifact::getFile));
}
private Set getAllowedDependencies() {
return project.getDependencies().stream().filter(dep -> {
if (skipToProcess(dep.getScope(), dep.getGroupId())) {
debug("SKIP : ", dep);
return false;
}
return true;
}).map(d -> versionlessKey(d.getGroupId(), d.getArtifactId(), d.getClassifier())).collect(Collectors.toSet());
}
private static String versionlessKey(String groupId, String artifactId, String classifier) {
if (classifier == null) {
return groupId + ":" + artifactId;
} else {
return groupId + ":" + artifactId + ":" + classifier;
}
}
private static boolean skipToProcess(String scope, String group) {
return !Artifact.SCOPE_PROVIDED.equals(scope) || isOpenLCoreDependency(group);
}
@Override
boolean isDisabled() {
return skipTests || skipITs;
}
@Override
String getHeader() {
return "OPENL VERIFY";
}
}