All Downloads are FREE. Search and download functionalities are using the official Maven repository.
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.wildfly.swarm.arquillian.adapter.UberjarSimpleContainer Maven / Gradle / Ivy
/**
* Copyright 2015-2016 Red Hat, Inc, and individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.swarm.arquillian.adapter;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jboss.arquillian.container.spi.client.container.DeploymentException;
import org.jboss.arquillian.container.spi.context.ContainerContext;
import org.jboss.arquillian.container.spi.context.DeploymentContext;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.container.ClassContainer;
import org.jboss.shrinkwrap.api.container.LibraryContainer;
import org.jboss.shrinkwrap.api.container.ManifestContainer;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenCoordinate;
import org.wildfly.swarm.Swarm;
import org.wildfly.swarm.arquillian.CreateSwarm;
import org.wildfly.swarm.arquillian.adapter.resources.ContextRoot;
import org.wildfly.swarm.arquillian.resolver.ShrinkwrapArtifactResolvingHelper;
import org.wildfly.swarm.bootstrap.util.BootstrapProperties;
import org.wildfly.swarm.bootstrap.util.TempFileManager;
import org.wildfly.swarm.internal.FileSystemLayout;
import org.wildfly.swarm.spi.api.DependenciesContainer;
import org.wildfly.swarm.spi.api.JARArchive;
import org.wildfly.swarm.spi.api.MarkerContainer;
import org.wildfly.swarm.spi.api.SwarmProperties;
import org.wildfly.swarm.spi.api.internal.SwarmInternalProperties;
import org.wildfly.swarm.tools.ArtifactSpec;
import org.wildfly.swarm.tools.BuildTool;
import org.wildfly.swarm.tools.DeclaredDependencies;
import org.wildfly.swarm.tools.exec.SwarmExecutor;
import org.wildfly.swarm.tools.exec.SwarmProcess;
public class UberjarSimpleContainer implements SimpleContainer {
static final String UBERJAR_SUFFIX = "-thorntail";
private final ContainerContext containerContext;
private final DeploymentContext deploymentContext;
public UberjarSimpleContainer(ContainerContext containerContext, DeploymentContext deploymentContext, Class> testClass) {
this.containerContext = containerContext;
this.deploymentContext = deploymentContext;
this.testClass = testClass;
}
@Override
public UberjarSimpleContainer requestedMavenArtifacts(Set artifacts) {
this.requestedMavenArtifacts = artifacts;
return this;
}
public UberjarSimpleContainer setJavaVmArguments(String javaVmArguments) {
this.javaVmArguments = javaVmArguments;
return this;
}
@Override
public void start(Archive> archive) throws Exception {
archive.add(EmptyAsset.INSTANCE, "META-INF/arquillian-testable");
ContextRoot contextRoot = null;
if (archive.getName().endsWith(".war")) {
contextRoot = new ContextRoot("/");
Node jbossWebNode = archive.as(WebArchive.class).get("WEB-INF/jboss-web.xml");
if (jbossWebNode != null) {
if (jbossWebNode.getAsset() != null) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(jbossWebNode.getAsset().openStream()))) {
String content = String.join("\n", reader.lines().collect(Collectors.toList()));
Pattern pattern = Pattern.compile("(.+) ");
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
contextRoot = new ContextRoot(matcher.group(1));
}
}
}
}
this.deploymentContext.getObjectStore().add(ContextRoot.class, contextRoot);
}
MainSpecifier mainSpecifier = containerContext.getObjectStore().get(MainSpecifier.class);
boolean annotatedCreateSwarm = false;
Method swarmMethod = getAnnotatedMethodWithAnnotation(this.testClass, CreateSwarm.class);
List> types = determineTypes(this.testClass);
// preflight check it
if (swarmMethod != null) {
if (Modifier.isStatic(swarmMethod.getModifiers())) {
// good to go
annotatedCreateSwarm = true;
types.add(CreateSwarm.class);
types.add(AnnotationBasedMain.class);
archive.as(JARArchive.class).addModule("org.wildfly.swarm.container");
archive.as(JARArchive.class).addModule("org.wildfly.swarm.configuration");
} else {
throw new IllegalArgumentException(
String.format("Method annotated with %s is %s but it is not static",
CreateSwarm.class.getSimpleName(),
swarmMethod));
}
}
if (types.size() > 0) {
try {
((ClassContainer>) archive).addClasses(types.toArray(new Class[types.size()]));
} catch (UnsupportedOperationException e) {
// TODO Remove the try/catch when SHRINKWRAP-510 is resolved and we update to latest SW
archive.as(JARArchive.class).addClasses(types.toArray(new Class[types.size()]));
}
}
final ShrinkwrapArtifactResolvingHelper resolvingHelper = ShrinkwrapArtifactResolvingHelper.defaultInstance();
BuildTool tool = new BuildTool(resolvingHelper)
.fractionDetectionMode(BuildTool.FractionDetectionMode.when_missing)
.bundleDependencies(false);
String additionalModules = System.getProperty(SwarmInternalProperties.BUILD_MODULES);
// See https://issues.jboss.org/browse/SWARM-571
if (null == additionalModules) {
// see if we can find it
File modulesDir = new File("target/classes/modules");
additionalModules = modulesDir.exists() ? modulesDir.getAbsolutePath() : null;
}
if (additionalModules != null) {
tool.additionalModules(Stream.of(additionalModules.split(":"))
.map(File::new)
.filter(File::exists)
.map(File::getAbsolutePath)
.collect(Collectors.toList()));
}
final SwarmExecutor executor = new SwarmExecutor().withDefaultSystemProperties();
if (annotatedCreateSwarm) {
executor.withProperty(AnnotationBasedMain.ANNOTATED_CLASS_NAME, this.testClass.getName());
}
if (contextRoot != null) {
executor.withProperty(SwarmProperties.CONTEXT_PATH, contextRoot.context());
}
executor.withProperty("thorntail.inhibit.auto-stop", "true");
String additionalRepos = System.getProperty(SwarmInternalProperties.BUILD_REPOS);
if (additionalRepos != null) {
additionalRepos = additionalRepos + ",";
} else {
additionalRepos = "";
}
additionalRepos = additionalRepos + "https://repository.jboss.org/nexus/content/groups/public/";
executor.withProperty("remote.maven.repo", additionalRepos);
// project dependencies
FileSystemLayout fsLayout = FileSystemLayout.create();
DeclaredDependencies declaredDependencies =
DependencyDeclarationFactory.newInstance(fsLayout).create(fsLayout, resolvingHelper);
tool.declaredDependencies(declaredDependencies);
// check for "org.wildfly.swarm.allDependencies" flag
// see DependenciesContainer#addAllDependencies()
if (archive instanceof DependenciesContainer) {
DependenciesContainer> depContainer = (DependenciesContainer>) archive;
if (depContainer.hasMarker(DependenciesContainer.ALL_DEPENDENCIES_MARKER)) {
munge(depContainer, declaredDependencies);
}
} else if (archive instanceof WebArchive) {
// Handle the default deployment of type WAR
WebArchive webArchive = (WebArchive) archive;
if (MarkerContainer.hasMarker(webArchive, DependenciesContainer.ALL_DEPENDENCIES_MARKER)) {
munge(webArchive, declaredDependencies);
}
}
tool.projectArchive(archive);
final String debug = System.getProperty(SwarmProperties.DEBUG_PORT);
if (debug != null) {
try {
executor.withDebug(Integer.parseInt(debug));
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
String.format("Failed to parse %s of \"%s\"", SwarmProperties.DEBUG_PORT, debug), e
);
}
}
if (mainSpecifier != null) {
tool.mainClass(mainSpecifier.getClassName());
String[] args = mainSpecifier.getArgs();
for (String arg : args) {
executor.withArgument(arg);
}
} else if (annotatedCreateSwarm) {
tool.mainClass(AnnotationBasedMain.class.getName());
} else {
Optional mainClassName = Optional.empty();
Node node = archive.get("META-INF/arquillian-main-class");
if (node != null && node.getAsset() != null) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(node.getAsset().openStream()))) {
mainClassName = reader.lines().findFirst();
}
}
tool.mainClass(mainClassName.orElse(Swarm.class.getName()));
}
if (this.testClass != null) {
tool.testClass(this.testClass.getName());
}
Archive> wrapped = null;
try {
wrapped = tool.build();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
if (BootstrapProperties.flagIsSet(SwarmInternalProperties.EXPORT_UBERJAR)) {
final File out = new File(wrapped.getName());
System.err.println("Exporting thorntail jar to " + out.getAbsolutePath());
wrapped.as(ZipExporter.class).exportTo(out, true);
}
/* for (Map.Entry each : wrapped.getContent().entrySet()) {
System.err.println("-> " + each.getKey());
}*/
File executable = File.createTempFile(TempFileManager.WFSWARM_TMP_PREFIX + "arquillian", UBERJAR_SUFFIX + ".jar");
wrapped.as(ZipExporter.class).exportTo(executable, true);
executable.deleteOnExit();
String mavenRepoLocal = System.getProperty("maven.repo.local");
if (mavenRepoLocal != null) {
executor.withProperty("maven.repo.local", mavenRepoLocal);
}
executor.withProperty("java.net.preferIPv4Stack", "true");
File processFile = File.createTempFile(TempFileManager.WFSWARM_TMP_PREFIX + "mainprocessfile", null);
executor.withProcessFile(processFile);
executor.withJVMArguments(getJavaVmArgumentsList());
executor.withExecutableJar(executable.toPath());
workingDirectory = TempFileManager.INSTANCE.newTempDirectory("arquillian", null);
executor.withWorkingDirectory(workingDirectory.toPath());
this.process = executor.execute();
this.process.getOutputStream().close();
this.process.awaitReadiness(2, TimeUnit.MINUTES);
if (!this.process.isAlive()) {
throw new DeploymentException("Process failed to start");
}
if (this.process.getError() != null) {
throw new DeploymentException("Error starting process", this.process.getError());
}
}
private & ManifestContainer>> void munge(C container, DeclaredDependencies declaredDependencies) {
for (ArtifactSpec artifact : declaredDependencies.getRuntimeExplicitAndTransientDependencies()) {
assert artifact.file != null : "artifact.file cannot be null at this point: " + artifact;
container.addAsLibrary(artifact.file);
}
try {
MarkerContainer.addMarker(container, "org.wildfly.swarm.allDependencies.added");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private List> determineTypes(Class> testClass) {
List> types = new ArrayList<>();
Class> clazz = testClass;
while (clazz != null && clazz != Object.class) {
types.add(clazz);
List> interfaces = Arrays.>asList(clazz.getInterfaces());
types.addAll(interfaces);
// Handle interfaces with inheritance
for (Class> iface : interfaces) {
List> superInterfaces = Arrays.>asList(iface.getInterfaces());
types.addAll(superInterfaces);
}
clazz = clazz.getSuperclass();
}
return types;
}
private void registerContainerFactory(Archive> archive, Class> clazz) {
archive.as(JavaArchive.class)
.addAsServiceProvider("org.wildfly.swarm.ContainerFactory",
clazz.getName())
.addClass(clazz);
archive.as(JARArchive.class).addModule("org.wildfly.swarm.container");
archive.as(JARArchive.class).addModule("org.wildfly.swarm.configuration");
}
@Override
public void stop() throws Exception {
this.process.stop(2, TimeUnit.MINUTES); // Because my laptop is slower than yours.
TempFileManager.deleteRecursively(workingDirectory);
}
private String ga(final MavenCoordinate coord) {
return String.format("%s:%s", coord.getGroupId(), coord.getArtifactId());
}
private String gav(final MavenCoordinate coord) {
return gav(coord.getGroupId(), coord.getArtifactId(), coord.getVersion());
}
private String gav(final String group, final String artifact, final String version) {
return String.format("%s:%s:%s", group, artifact, version);
}
private List getJavaVmArgumentsList() {
if (this.javaVmArguments == null) {
return Collections.emptyList();
}
List args = new ArrayList<>();
StringTokenizer tokens = new StringTokenizer(this.javaVmArguments);
while (tokens.hasMoreTokens()) {
args.add(tokens.nextToken());
}
return args;
}
private final Class> testClass;
private SwarmProcess process;
private Set requestedMavenArtifacts = new HashSet<>();
private String javaVmArguments;
private File workingDirectory;
}