use of io.quarkus.builder.BuildChainBuilder in project quarkus by quarkusio.
the class QuarkusDeployableContainer method deploy.
@SuppressWarnings("rawtypes")
@Override
public ProtocolMetaData deploy(Archive<?> archive) throws DeploymentException {
old = Thread.currentThread().getContextClassLoader();
if (testClass.get() == null) {
throw new IllegalStateException("Test class not available");
}
Class testJavaClass = testClass.get().getJavaClass();
// some TCK tests embed random libraries such as old versions of Jackson databind
// this breaks quarkus, so we just skip them
boolean skipLibraries = Boolean.getBoolean("io.quarkus.arquillian.skip-libraries");
try {
// Export the test archive
Path tmpLocation = Files.createTempDirectory("quarkus-arquillian-test");
deploymentLocation.set(tmpLocation);
archive.as(ExplodedExporter.class).exportExplodedInto(tmpLocation.toFile());
Path appLocation;
Set<Path> libraries = new HashSet<>();
if (archive instanceof WebArchive) {
// Quarkus does not support the WAR layout and so adapt the layout (similarly to quarkus-war-launcher)
appLocation = tmpLocation.resolve("app").toAbsolutePath();
// WEB-INF/lib -> lib/
if (!skipLibraries) {
if (Files.exists(tmpLocation.resolve("WEB-INF/lib"))) {
Files.move(tmpLocation.resolve("WEB-INF/lib"), tmpLocation.resolve("lib"));
}
}
// WEB-INF/classes -> archive/
if (Files.exists(tmpLocation.resolve("WEB-INF/classes"))) {
Files.move(tmpLocation.resolve("WEB-INF/classes"), appLocation);
} else {
Files.createDirectory(appLocation);
}
// META-INF -> archive/META-INF/
if (Files.exists(tmpLocation.resolve("META-INF"))) {
if (Files.exists(appLocation.resolve("META-INF"))) {
// Target directory not empty.
try (Stream<Path> fileTreeElements = Files.walk(tmpLocation.resolve("META-INF"), 2)) {
fileTreeElements.forEach(p -> {
try {
Files.createFile(p);
} catch (FileAlreadyExistsException faee) {
// Do Nothing
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
} else {
Files.move(tmpLocation.resolve("META-INF"), appLocation.resolve("META-INF"));
}
}
// WEB-INF -> archive/WEB-INF
if (Files.exists(tmpLocation.resolve("WEB-INF"))) {
Files.move(tmpLocation.resolve("WEB-INF"), appLocation.resolve("WEB-INF"));
}
// Collect all libraries
if (Files.exists(tmpLocation.resolve("lib"))) {
try (Stream<Path> libs = Files.walk(tmpLocation.resolve("lib"), 1)) {
libs.forEach((i) -> {
if (i.getFileName().toString().endsWith(".jar")) {
libraries.add(i);
}
});
}
}
} else {
appLocation = tmpLocation;
}
List<Consumer<BuildChainBuilder>> customizers = new ArrayList<>();
// Test class is a bean
customizers.add(new Consumer<BuildChainBuilder>() {
@Override
public void accept(BuildChainBuilder buildChainBuilder) {
buildChainBuilder.addBuildStep(new BuildStep() {
@Override
public void execute(BuildContext context) {
context.produce(AdditionalBeanBuildItem.unremovableOf(testJavaClass));
}
}).produces(AdditionalBeanBuildItem.class).build();
}
});
QuarkusBootstrap.Builder bootstrapBuilder = QuarkusBootstrap.builder().setApplicationRoot(appLocation).setProjectRoot(appLocation).setIsolateDeployment(false).setFlatClassPath(true).setMode(QuarkusBootstrap.Mode.TEST);
for (Path i : libraries) {
bootstrapBuilder.addAdditionalApplicationArchive(new AdditionalDependency(i, false, true));
}
// Path testLocation = PathTestHelper.getTestClassesLocation(testJavaClass);
// bootstrapBuilder.setProjectRoot(PathTestHelper.getTestClassesLocation(testJavaClass));
CuratedApplication curatedApplication = bootstrapBuilder.build().bootstrap();
AugmentAction augmentAction = new AugmentActionImpl(curatedApplication, customizers);
StartupAction app = augmentAction.createInitialRuntimeApplication();
RunningQuarkusApplication runningQuarkusApplication = app.run();
appClassloader.set(runningQuarkusApplication.getClassLoader());
runningApp.set(runningQuarkusApplication);
Thread.currentThread().setContextClassLoader(runningQuarkusApplication.getClassLoader());
// Instantiate the real test instance
testInstance = TestInstantiator.instantiateTest(testJavaClass, runningQuarkusApplication.getClassLoader());
// its pretty bogus
if (Boolean.getBoolean("io.quarkus.arquillian.copy-fields")) {
Class<?> dest = testInstance.getClass();
Class<?> source = testClass.get().getJavaClass();
while (source != Object.class) {
for (Field f : source.getDeclaredFields()) {
try {
if (Modifier.isStatic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers())) {
Field df = dest.getDeclaredField(f.getName());
df.setAccessible(true);
f.setAccessible(true);
df.set(null, f.get(null));
}
} catch (Exception e) {
LOGGER.error("Failed to copy static field", e);
}
}
source = source.getSuperclass();
dest = dest.getSuperclass();
}
}
} catch (Throwable t) {
// clone the exception into the correct class loader
Throwable nt;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ObjectOutputStream a = new ObjectOutputStream(out)) {
a.writeObject(t);
a.close();
nt = (Throwable) new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject();
} catch (Exception e) {
throw new DeploymentException("Unable to start the runtime runner", t);
}
throw new DeploymentException("Unable to start the runtime runner", nt);
} finally {
Thread.currentThread().setContextClassLoader(old);
}
ProtocolMetaData metadata = new ProtocolMetaData();
// TODO: fix this
String testUri = TestHTTPResourceManager.getUri(runningApp.get());
System.setProperty("test.url", testUri);
URI uri = URI.create(testUri);
HTTPContext httpContext = new HTTPContext(uri.getHost(), uri.getPort());
// This is to work around https://github.com/arquillian/arquillian-core/issues/216
httpContext.add(new Servlet("dummy", "/"));
metadata.addContext(httpContext);
return metadata;
}
use of io.quarkus.builder.BuildChainBuilder in project quarkus by quarkusio.
the class MetricsFromExtensionTestCase method buildCustomizer.
protected static Consumer<BuildChainBuilder> buildCustomizer() {
return new Consumer<BuildChainBuilder>() {
// This represents the extension.
@Override
public void accept(BuildChainBuilder builder) {
builder.addBuildStep(context -> {
BeanArchiveIndexBuildItem indexBuildItem = context.consume(BeanArchiveIndexBuildItem.class);
for (ClassInfo clazz : indexBuildItem.getIndex().getKnownClasses()) {
for (MethodInfo method : clazz.methods()) {
if (method.name().startsWith("countMePlease")) {
Metadata metricMetadata = Metadata.builder().withType(MetricType.COUNTER).withName(clazz.name().toString() + "." + method.name()).build();
MetricBuildItem buildItem = new MetricBuildItem.Builder().metadata(metricMetadata).enabled(true).build();
context.produce(buildItem);
} else if (method.name().startsWith("countMeInBaseScope")) {
Metadata metricMetadata = Metadata.builder().withType(MetricType.COUNTER).withName(clazz.name().toString() + "." + method.name()).build();
MetricBuildItem buildItem = new MetricBuildItem.Builder().metadata(metricMetadata).registryType(MetricRegistry.Type.BASE).enabled(true).build();
context.produce(buildItem);
}
}
}
}).consumes(BeanArchiveIndexBuildItem.class).produces(MetricBuildItem.class).build();
}
};
}
use of io.quarkus.builder.BuildChainBuilder in project quarkus by quarkusio.
the class MongoNamedClientClientBuildItemConsumerTest method buildCustomizer.
protected static Consumer<BuildChainBuilder> buildCustomizer() {
return new Consumer<BuildChainBuilder>() {
// This represents the extension.
@Override
public void accept(BuildChainBuilder builder) {
builder.addBuildStep(context -> {
ApplicationArchivesBuildItem archive = context.consume(ApplicationArchivesBuildItem.class);
context.produce(Collections.singletonList(new MongoClientNameBuildItem("second")));
}).consumes(ApplicationArchivesBuildItem.class).produces(MongoClientNameBuildItem.class).build();
builder.addBuildStep(context -> {
List<MongoClientBuildItem> mongoClientBuildItems = context.consumeMulti(MongoClientBuildItem.class);
context.produce(new FeatureBuildItem("dummy"));
}).consumes(MongoClientBuildItem.class).produces(FeatureBuildItem.class).build();
}
};
}
use of io.quarkus.builder.BuildChainBuilder in project quarkus by quarkusio.
the class GeneratedJaxRsResourceTest method buildCustomizer.
protected static Consumer<BuildChainBuilder> buildCustomizer() {
return new Consumer<>() {
/**
* This represents the extension that generates a JAX-RS resource like:
*
* <pre>
* {@code
* @Path("/test')
* public class TestResource {
*
* @GET
* public String test() {
* return "test";
* }
* }
* }
* </pre>
*/
@Override
public void accept(BuildChainBuilder builder) {
builder.addBuildStep(context -> {
BuildProducer<GeneratedJaxRsResourceBuildItem> producer = context::produce;
ClassOutput classOutput = new GeneratedJaxRsResourceGizmoAdaptor(producer);
try (ClassCreator classCreator = ClassCreator.builder().classOutput(classOutput).className("com.example.TestResource").build()) {
classCreator.addAnnotation(Path.class).addValue("value", "test");
MethodCreator methodCreator = classCreator.getMethodCreator("test", String.class);
methodCreator.addAnnotation(GET.class);
methodCreator.returnValue(methodCreator.load("test"));
}
}).produces(GeneratedJaxRsResourceBuildItem.class).build();
}
};
}
use of io.quarkus.builder.BuildChainBuilder in project quarkus by quarkusio.
the class ExtensionLoader method loadStepsFrom.
/**
* Load all the build steps from the given class loader.
*
* @param classLoader the class loader
* @param buildSystemProps the build system properties to use
* @param launchMode launch mode
* @param configCustomizer configuration customizer
* @return a consumer which adds the steps to the given chain builder
* @throws IOException if the class loader could not load a resource
* @throws ClassNotFoundException if a build step class is not found
*/
public static Consumer<BuildChainBuilder> loadStepsFrom(ClassLoader classLoader, Properties buildSystemProps, ApplicationModel appModel, LaunchMode launchMode, DevModeType devModeType) throws IOException, ClassNotFoundException {
// populate with all known types
List<Class<?>> roots = new ArrayList<>();
for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, CONFIG_ROOTS_LIST)) {
final ConfigRoot annotation = clazz.getAnnotation(ConfigRoot.class);
if (annotation == null) {
cfgLog.warnf("Ignoring configuration root %s because it has no annotation", clazz);
} else {
roots.add(clazz);
}
}
final BuildTimeConfigurationReader reader = new BuildTimeConfigurationReader(roots);
// now prepare & load the build configuration
final SmallRyeConfigBuilder builder = ConfigUtils.configBuilder(false, launchMode);
final DefaultValuesConfigurationSource ds1 = new DefaultValuesConfigurationSource(reader.getBuildTimePatternMap());
final DefaultValuesConfigurationSource ds2 = new DefaultValuesConfigurationSource(reader.getBuildTimeRunTimePatternMap());
final PropertiesConfigSource pcs = new PropertiesConfigSource(buildSystemProps, "Build system");
final Map<String, String> platformProperties = appModel.getPlatformProperties();
if (platformProperties.isEmpty()) {
builder.withSources(ds1, ds2, pcs);
} else {
final KeyMap<String> props = new KeyMap<>(platformProperties.size());
for (Map.Entry<String, String> prop : platformProperties.entrySet()) {
props.findOrAdd(new NameIterator(prop.getKey())).putRootValue(prop.getValue());
}
final KeyMapBackedConfigSource platformConfigSource = new KeyMapBackedConfigSource("Quarkus platform", // (see io.quarkus.deployment.configuration.DefaultValuesConfigurationSource)
Integer.MIN_VALUE + 1000, props);
builder.withSources(ds1, ds2, platformConfigSource, pcs);
}
for (ConfigClassWithPrefix mapping : reader.getBuildTimeVisibleMappings()) {
builder.withMapping(mapping.getKlass(), mapping.getPrefix());
}
final SmallRyeConfig src = builder.build();
// install globally
QuarkusConfigFactory.setConfig(src);
final ConfigProviderResolver cpr = ConfigProviderResolver.instance();
try {
cpr.releaseConfig(cpr.getConfig());
} catch (IllegalStateException ignored) {
// just means no config was installed, which is fine
}
final BuildTimeConfigurationReader.ReadResult readResult = reader.readConfiguration(src);
final BooleanSupplierFactoryBuildItem bsf = new BooleanSupplierFactoryBuildItem(readResult, launchMode, devModeType);
Consumer<BuildChainBuilder> result = Functions.discardingConsumer();
// BooleanSupplier factory
result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
bc.produce(bsf);
}).produces(BooleanSupplierFactoryBuildItem.class).build());
// the proxy objects used for run time config in the recorders
Map<Class<?>, Object> proxies = new HashMap<>();
for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, "META-INF/quarkus-build-steps.list")) {
try {
result = result.andThen(ExtensionLoader.loadStepsFromClass(clazz, readResult, proxies, bsf));
} catch (Throwable e) {
throw new RuntimeException("Failed to load steps from " + clazz, e);
}
}
// this has to be an identity hash map else the recorder will get angry
Map<Object, FieldDescriptor> rootFields = new IdentityHashMap<>();
Map<Object, ConfigClassWithPrefix> mappingClasses = new IdentityHashMap<>();
for (Map.Entry<Class<?>, Object> entry : proxies.entrySet()) {
// ConfigRoot
RootDefinition root = readResult.getAllRootsByClass().get(entry.getKey());
if (root != null) {
rootFields.put(entry.getValue(), root.getDescriptor());
continue;
}
// ConfigMapping
ConfigClassWithPrefix mapping = readResult.getAllMappings().get(entry.getKey());
if (mapping != null) {
mappingClasses.put(entry.getValue(), mapping);
continue;
}
throw new IllegalStateException("No config found for " + entry.getKey());
}
result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
bc.produce(new ConfigurationBuildItem(readResult));
bc.produce(new RunTimeConfigurationProxyBuildItem(proxies));
ObjectLoader rootLoader = new ObjectLoader() {
public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
return body.readStaticField(rootFields.get(obj));
}
public boolean canHandleObject(final Object obj, final boolean staticInit) {
return rootFields.containsKey(obj);
}
};
ObjectLoader mappingLoader = new ObjectLoader() {
@Override
public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
ConfigClassWithPrefix mapping = mappingClasses.get(obj);
MethodDescriptor getConfig = MethodDescriptor.ofMethod(ConfigProvider.class, "getConfig", Config.class);
ResultHandle config = body.invokeStaticMethod(getConfig);
MethodDescriptor getMapping = MethodDescriptor.ofMethod(SmallRyeConfig.class, "getConfigMapping", Object.class, Class.class, String.class);
return body.invokeVirtualMethod(getMapping, config, body.loadClass(mapping.getKlass()), body.load(mapping.getPrefix()));
}
@Override
public boolean canHandleObject(final Object obj, final boolean staticInit) {
return mappingClasses.containsKey(obj);
}
};
bc.produce(new BytecodeRecorderObjectLoaderBuildItem(rootLoader));
bc.produce(new BytecodeRecorderObjectLoaderBuildItem(mappingLoader));
}).produces(ConfigurationBuildItem.class).produces(RunTimeConfigurationProxyBuildItem.class).produces(BytecodeRecorderObjectLoaderBuildItem.class).build());
return result;
}
Aggregations