Skip to content

Commit

Permalink
Merge pull request #9436 from stuartwdouglas/9296
Browse files Browse the repository at this point in the history
Fix issue with build time config in dev mode
  • Loading branch information
gsmet authored May 20, 2020
2 parents 21a70d8 + fe20ae9 commit 1061f54
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -616,10 +616,7 @@ public void run() {
clinit.invokeStaticMethod(initGroup, clinitConfig, clinitNameBuilder, instance);
clinit.invokeVirtualMethod(SB_SET_LENGTH, clinitNameBuilder, clInitOldLen);
if (devMode) {
//we don't regenerate this class in dev mode, but we do allow config to be reloaded
instance = readConfig.invokeStaticMethod(ctor);
// assign instance to field
readConfig.writeStaticField(rootFieldDescriptor, instance);
instance = readConfig.readStaticField(rootFieldDescriptor);
if (!rootName.isEmpty()) {
readConfig.invokeVirtualMethod(SB_APPEND_CHAR, readConfigNameBuilder, readConfig.load('.'));
readConfig.invokeVirtualMethod(SB_APPEND_STRING, readConfigNameBuilder,
Expand Down Expand Up @@ -668,58 +665,14 @@ public void run() {
}
}

ResultHandle nameSet;
ResultHandle iterator;

// generate sweep for clinit
nameSet = clinit.invokeVirtualMethod(SRC_GET_PROPERTY_NAMES, clinitConfig);
iterator = clinit.invokeInterfaceMethod(ITRA_ITERATOR, nameSet);
configSweepLoop(siParserBody, clinit, clinitConfig);

try (BytecodeCreator sweepLoop = clinit.createScope()) {
try (BytecodeCreator hasNext = sweepLoop.ifNonZero(sweepLoop.invokeInterfaceMethod(ITR_HAS_NEXT, iterator))
.trueBranch()) {

final ResultHandle key = hasNext.checkCast(hasNext.invokeInterfaceMethod(ITR_NEXT, iterator), String.class);
// NameIterator keyIter = new NameIterator(key);
final ResultHandle keyIter = hasNext.newInstance(NI_NEW_STRING, key);
// if (! keyIter.hasNext()) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeVirtualMethod(NI_HAS_NEXT, keyIter)).falseBranch().continueScope(sweepLoop);
// if (! keyIter.nextSegmentEquals("quarkus")) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeVirtualMethod(NI_NEXT_EQUALS, keyIter, hasNext.load("quarkus")))
.falseBranch().continueScope(sweepLoop);
// keyIter.next(); // skip "quarkus"
hasNext.invokeVirtualMethod(NI_NEXT, keyIter);
// parse(config, keyIter);
hasNext.invokeStaticMethod(siParserBody, clinitConfig, keyIter);
// continue sweepLoop;
hasNext.continueScope(sweepLoop);
}
if (devMode) {
configSweepLoop(siParserBody, readConfig, runTimeConfig);
}

// generate sweep for run time
nameSet = readConfig.invokeVirtualMethod(SRC_GET_PROPERTY_NAMES, runTimeConfig);
iterator = readConfig.invokeInterfaceMethod(ITRA_ITERATOR, nameSet);

try (BytecodeCreator sweepLoop = readConfig.createScope()) {
try (BytecodeCreator hasNext = sweepLoop.ifNonZero(sweepLoop.invokeInterfaceMethod(ITR_HAS_NEXT, iterator))
.trueBranch()) {

final ResultHandle key = hasNext.checkCast(hasNext.invokeInterfaceMethod(ITR_NEXT, iterator), String.class);
// NameIterator keyIter = new NameIterator(key);
final ResultHandle keyIter = hasNext.newInstance(NI_NEW_STRING, key);
// if (! keyIter.hasNext()) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeVirtualMethod(NI_HAS_NEXT, keyIter)).falseBranch().continueScope(sweepLoop);
// if (! keyIter.nextSegmentEquals("quarkus")) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeVirtualMethod(NI_NEXT_EQUALS, keyIter, hasNext.load("quarkus")))
.falseBranch().continueScope(sweepLoop);
// keyIter.next(); // skip "quarkus"
hasNext.invokeVirtualMethod(NI_NEXT, keyIter);
// parse(config, keyIter);
hasNext.invokeStaticMethod(rtParserBody, runTimeConfig, keyIter);
// continue sweepLoop;
hasNext.continueScope(sweepLoop);
}
}
configSweepLoop(rtParserBody, readConfig, runTimeConfig);

// generate ensure-initialized method
// the point of this method is simply to initialize the Config class
Expand Down Expand Up @@ -783,6 +736,34 @@ public void run() {
generateDefaultValuesConfigSourceClass(buildTimeRunTimePatternMap, BTRTDVCS_CLASS_NAME);
}

private static void configSweepLoop(MethodDescriptor parserBody, MethodCreator method, ResultHandle config) {
ResultHandle nameSet;
ResultHandle iterator;
nameSet = method.invokeVirtualMethod(SRC_GET_PROPERTY_NAMES, config);
iterator = method.invokeInterfaceMethod(ITRA_ITERATOR, nameSet);

try (BytecodeCreator sweepLoop = method.createScope()) {
try (BytecodeCreator hasNext = sweepLoop.ifNonZero(sweepLoop.invokeInterfaceMethod(ITR_HAS_NEXT, iterator))
.trueBranch()) {

final ResultHandle key = hasNext.checkCast(hasNext.invokeInterfaceMethod(ITR_NEXT, iterator), String.class);
// NameIterator keyIter = new NameIterator(key);
final ResultHandle keyIter = hasNext.newInstance(NI_NEW_STRING, key);
// if (! keyIter.hasNext()) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeVirtualMethod(NI_HAS_NEXT, keyIter)).falseBranch().continueScope(sweepLoop);
// if (! keyIter.nextSegmentEquals("quarkus")) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeVirtualMethod(NI_NEXT_EQUALS, keyIter, hasNext.load("quarkus")))
.falseBranch().continueScope(sweepLoop);
// keyIter.next(); // skip "quarkus"
hasNext.invokeVirtualMethod(NI_NEXT, keyIter);
// parse(config, keyIter);
hasNext.invokeStaticMethod(parserBody, config, keyIter);
// continue sweepLoop;
hasNext.continueScope(sweepLoop);
}
}
}

private void installConfiguration(ResultHandle config, MethodCreator methodCreator) {
// install config
methodCreator.invokeStaticMethod(QCF_SET_CONFIG, config);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.quarkus.elytron.security.jdbc;

import java.util.Arrays;
import java.util.stream.Stream;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusDevModeTest;
import io.restassured.RestAssured;

//see https://github.com/quarkusio/quarkus/issues/9296
public class CustomRoleDecoderDevModeTest extends JdbcSecurityRealmTest {

static Class[] testClassesWithCustomRoleDecoder = Stream.concat(
Arrays.stream(testClasses),
Arrays.stream(new Class[] { CustomRoleDecoder.class })).toArray(Class[]::new);

@RegisterExtension
static final QuarkusDevModeTest config = new QuarkusDevModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(testClassesWithCustomRoleDecoder)
.addAsResource("custom-role-decoder/import.sql")
.addAsResource("custom-role-decoder/application.properties", "application.properties"));

@Test
public void testConfigChange() {
RestAssured.given().auth().preemptive().basic("user", "user")
.when().get("/servlet-secured").then()
.statusCode(200);
//break the build time config
config.modifyResourceFile("application.properties",
s -> s.replace("quarkus.security.jdbc.principal-query.attribute-mappings.0.index=2",
"quarkus.security.jdbc.principal-query.attribute-mappings.0.index=3"));
RestAssured.given().auth().preemptive().basic("user", "user")
.when().get("/servlet-secured").then()
.statusCode(500);

//now fix it again
config.modifyResourceFile("application.properties",
s -> s.replace("quarkus.security.jdbc.principal-query.attribute-mappings.0.index=3",
"quarkus.security.jdbc.principal-query.attribute-mappings.0.index=2"));
RestAssured.given().auth().preemptive().basic("user", "user")
.when().get("/servlet-secured").then()
.statusCode(200);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.quarkus.flyway.test;

import static org.hamcrest.CoreMatchers.containsString;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusDevModeTest;
import io.restassured.RestAssured;

// see https://github.com/quarkusio/quarkus/issues/9415
public class FlywayMultiDataSourcesDevModeTest {

@RegisterExtension
static final QuarkusDevModeTest config = new QuarkusDevModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(MultiDataSourcesDevModeEndpoint.class)
.addAsResource("config-for-multiple-datasources.properties", "application.properties"));

@Test
public void testProperConfigApplied() {
RestAssured.get("/fly").then()
.statusCode(200)
.body(containsString("db/location1,db/location2"));

RestAssured.get("/fly?name=users").then()
.statusCode(200)
.body(containsString("db/users/location1,db/users/location2"));

RestAssured.get("/fly?name=inventory").then()
.statusCode(200)
.body(containsString("db/inventory/location1,db/inventory/location"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.quarkus.flyway.test;

import java.util.Arrays;
import java.util.stream.Collectors;

import javax.inject.Inject;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.Location;
import org.flywaydb.core.api.configuration.Configuration;

import io.quarkus.flyway.FlywayDataSource;

@Path("/fly")
public class MultiDataSourcesDevModeEndpoint {

@Inject
Flyway flywayDefault;

@Inject
@FlywayDataSource("users")
Flyway flywayUsers;

@Inject
@FlywayDataSource("inventory")
Flyway flywayInventory;

@GET
@Produces("text/plain")
public String locations(@QueryParam("name") @DefaultValue("default") String name) {
Configuration configuration;
if ("default".equals(name)) {
configuration = flywayDefault.getConfiguration();
} else if ("users".equals(name)) {
configuration = flywayUsers.getConfiguration();
} else if ("inventory".equals(name)) {
configuration = flywayInventory.getConfiguration();
} else {
throw new RuntimeException("Flyway " + name + " not found");
}

return Arrays.stream(configuration.getLocations()).map(Location::getPath).collect(Collectors.joining(","));
}

}

0 comments on commit 1061f54

Please sign in to comment.