Skip to content

Commit

Permalink
Add the ability to inject configuration into build steps
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Nov 21, 2018
1 parent d4c26d0 commit 5095064
Show file tree
Hide file tree
Showing 32 changed files with 972 additions and 542 deletions.
28 changes: 2 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,29 +366,5 @@ however this will probably be expanded over time.
Shamrock has the concept of 'application classes'. These are classes that should be indexed via jandex, and acted on
via deployment processors.

By default only the classes in the current application are indexed, however it is possible to include additional classes.

Note that at the moment loading pre-computed indexes is not supported, and likely is out of scope of the PoC.

Three different mechanisms are provided to do this. The most common one will be to define application marker files.
If any of these files are discovered on the class path then the archive that contains these files will be considered
an application class. The most common of these marker files will be `META-INF/beans.xml`.

There are two different configuration based approaches both of them configured in `shamrock-build.yaml`.

* `index-dependencies`
This key must contain a list of maven artifacts, in either group:artifact or group:artifact:classifier format. If an
artifact is listed under this key it will be indexed. Note that this should not be used for artifacts that are part
of the current project, as when running from an IDE it is not possible to reliably determine the artifactId. In this
case you should use the `index-jar` method.

An example of this index config is:

```
index-dependencies:
- "io.smallrye:smallrye-health"
```
* `index-jar`
If this key is present and set to `true` then the contents of this jar will be indexed.
By default only the classes in the current application are indexed, however it is possible to include additional classes
by pre-indexing with the Jandex maven plugin.
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@

import static org.jboss.shamrock.annotations.ExecutionTime.STATIC_INIT;

import java.util.Optional;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.logging.Logger;
import org.jboss.shamrock.agroal.runtime.DataSourceConfig;
import org.jboss.shamrock.agroal.runtime.DataSourceProducer;
import org.jboss.shamrock.agroal.runtime.DataSourceTemplate;
import org.jboss.shamrock.annotations.BuildProducer;
import org.jboss.shamrock.annotations.BuildStep;
import org.jboss.shamrock.annotations.Record;
import org.jboss.shamrock.deployment.buildconfig.BuildConfig;
import org.jboss.shamrock.deployment.builditem.AdditionalBeanBuildItem;
import org.jboss.shamrock.deployment.builditem.substrate.ReflectiveClassBuildItem;
import org.jboss.shamrock.deployment.cdi.BeanContainerListenerBuildItem;
import org.jboss.shamrock.deployment.recording.RecorderContext;
import org.jboss.shamrock.runtime.ConfiguredValue;

class AgroalProcessor {

private static final Logger log = Logger.getLogger(AgroalProcessor.class);

/**
* The datasource configuration
*/
@ConfigProperty(name = "shamrock.datasource")
Optional<DataSourceConfig> dataSourceConfig;


@BuildStep
AdditionalBeanBuildItem registerBean() {
Expand All @@ -24,8 +34,8 @@ AdditionalBeanBuildItem registerBean() {

@Record(STATIC_INIT)
@BuildStep
BeanContainerListenerBuildItem build(BuildConfig config,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass, DataSourceTemplate template, RecorderContext bc) throws Exception {
BeanContainerListenerBuildItem build(
BuildProducer<ReflectiveClassBuildItem> reflectiveClass, DataSourceTemplate template) throws Exception {
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false,
io.agroal.pool.ConnectionHandler[].class.getName(),
io.agroal.pool.ConnectionHandler.class.getName(),
Expand All @@ -34,32 +44,14 @@ BeanContainerListenerBuildItem build(BuildConfig config,
java.sql.ResultSet.class.getName(),
java.sql.ResultSet[].class.getName()
));
BuildConfig.ConfigNode ds = config.getApplicationConfig().get("datasource");
if (ds.isNull()) {
if (!dataSourceConfig.isPresent()) {
log.warn("Agroal extension was included in build however no data source has been defined");
return null;
}
String driver = ds.get("driver").asString();
String url = ds.get("url").asString();
ConfiguredValue configuredDriver = new ConfiguredValue("datasource.driver", driver);
ConfiguredValue configuredURL = new ConfiguredValue("datasource.url", url);
if (configuredDriver.getValue() == null) {
throw new RuntimeException("Driver is required (property 'driver' under 'datasource')");
}
if (configuredURL.getValue() == null) {
throw new RuntimeException("JDBC URL is required (property 'url' under 'datasource')");
}
String userName = ds.get("username").asString();
ConfiguredValue configuredUsername = new ConfiguredValue("datasource.user", userName);
String password = ds.get("password").asString();
ConfiguredValue configuredPassword = new ConfiguredValue("datasource.password", password);

final Integer minSize = ds.get("minSize").asInteger();
final Integer maxSize = ds.get("maxSize").asInteger();


reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, driver));

return new BeanContainerListenerBuildItem(template.addDatasource(configuredURL.getValue(), bc.classProxy(configuredDriver.getValue()), configuredUsername.getValue(), configuredPassword.getValue(), minSize, maxSize));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, dataSourceConfig.get().driver));
return new BeanContainerListenerBuildItem(template.addDatasource(dataSourceConfig.get()));

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.jboss.shamrock.agroal.runtime;

import java.util.Optional;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.shamrock.runtime.ConfiguredType;

@ConfiguredType
public class DataSourceConfig {

/**
* The datasource driver class name
*/
@ConfigProperty(name = "driver")
public String driver;

/**
* The datasource URL
*/
@ConfigProperty(name = "url")
public String url;

/**
* The datasource username
*/
@ConfigProperty(name = "username")
public Optional<String> user;

/**
* The datasource password
*/
@ConfigProperty(name = "password")
public Optional<String> password;

/**
* The datasource pool minimum size
*/
@ConfigProperty(name = "minSize", defaultValue = "5")
public int minSize;

/**
* The datasource pool maximum size
*/
@ConfigProperty(name = "maxSize", defaultValue = "20")
public int maxSize;

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,25 @@
@Template
public class DataSourceTemplate {

public BeanContainerListener addDatasource(
String url, Class driver,
String userName, String password, Integer minSize, Integer maxSize) {
public BeanContainerListener addDatasource(DataSourceConfig config) {
return new BeanContainerListener() {
@Override
public void created(BeanContainer beanContainer) {
DataSourceProducer producer = beanContainer.instance(DataSourceProducer.class);
producer.setDriver(driver);
producer.setUrl(url);
producer.setUserName(userName);
producer.setPassword(password);
producer.setMinSize(minSize);
producer.setMaxSize(maxSize);
try {
producer.setDriver(Class.forName(config.driver, true, Thread.currentThread().getContextClassLoader()));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
producer.setUrl(config.url);
if (config.user.isPresent()) {
producer.setUserName(config.user.get());
}
if (config.password.isPresent()) {
producer.setPassword(config.password.get());
}
producer.setMinSize(config.minSize);
producer.setMaxSize(config.maxSize);
}
};
}
Expand Down
8 changes: 7 additions & 1 deletion builder/src/main/java/org/jboss/builder/Execution.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ BuildResult run() throws BuildException {
}
for (Diagnostic diagnostic : diagnostics) {
if (diagnostic.getLevel() == Diagnostic.Level.ERROR) {
throw new BuildException("Build failed due to errors", Collections.unmodifiableList(diagnostics));
BuildException failed = new BuildException("Build failed due to errors",diagnostic.getThrown(), Collections.unmodifiableList(diagnostics));
for(Diagnostic i : diagnostics) {
if(i.getThrown() != null && i.getThrown() != diagnostic.getThrown()) {
failed.addSuppressed(i.getThrown());
}
}
throw failed;
}
}
if (lastStepCount.get() > 0) throw new BuildException("Extra steps left over", Collections.emptyList());
Expand Down
Loading

0 comments on commit 5095064

Please sign in to comment.