Skip to content

Commit

Permalink
KEYCLOAK-1678 Fixed app-server containers' handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
tkyjovsk committed Feb 5, 2016
1 parent 3a51b35 commit 58084d5
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 134 deletions.
Expand Up @@ -4,7 +4,7 @@
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import org.jboss.arquillian.container.spi.Container; import org.jboss.arquillian.container.spi.event.container.BeforeDeploy;
import org.jboss.arquillian.container.test.api.ContainerController; import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.core.api.Instance; import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.InstanceProducer; import org.jboss.arquillian.core.api.InstanceProducer;
Expand Down Expand Up @@ -34,16 +34,15 @@ public class AppServerTestEnricher {
private InstanceProducer<TestContext> testContextProducer; private InstanceProducer<TestContext> testContextProducer;
private TestContext testContext; private TestContext testContext;


@Inject
private Instance<ContainerController> containerController;

public static String getAppServerQualifier(Class testClass) { public static String getAppServerQualifier(Class testClass) {
Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class); Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AppServerContainer.class);


String appServerQ = (annotatedClass == null ? null String appServerQ = (annotatedClass == null ? null
: annotatedClass.getAnnotation(AppServerContainer.class).value()); : annotatedClass.getAnnotation(AppServerContainer.class).value());


return appServerQ; return appServerQ == null || appServerQ.isEmpty()
? getAuthServerQualifier() // app server == auth server
: appServerQ;
} }


public static String getAppServerContextRoot() { public static String getAppServerContextRoot() {
Expand All @@ -60,12 +59,26 @@ public static String getAppServerContextRoot(int clusterPortOffset) {
: "http://localhost:" + (httpPort + clusterPortOffset); : "http://localhost:" + (httpPort + clusterPortOffset);
} }


private ContainerInfo initializeAppServerInfo(Container appServerContainer) { public void updateTestContextWithAppServerInfo(@Observes(precedence = 1) BeforeClass event) {
return initializeAppServerInfo(appServerContainer, 0); testContext = testContextProducer.get();
String appServerQualifier = getAppServerQualifier(testContext.getTestClass());
for (ContainerInfo container : testContext.getSuiteContext().getContainers()) {
if (container.getQualifier().equals(appServerQualifier)) {
testContext.setAppServerInfo(updateWithAppServerInfo(container));
}
}
// validate app server
if (appServerQualifier != null && testContext.getAppServerInfo() == null) {
throw new RuntimeException(String.format("No app server container matching '%s' was activated. Check if defined and enabled in arquillian.xml.", appServerQualifier));
}
log.info("\n\n" + testContext);
}

private ContainerInfo updateWithAppServerInfo(ContainerInfo appServerInfo) {
return updateWithAppServerInfo(appServerInfo, 0);
} }


private ContainerInfo initializeAppServerInfo(Container appServerContainer, int clusterPortOffset) { private ContainerInfo updateWithAppServerInfo(ContainerInfo appServerInfo, int clusterPortOffset) {
ContainerInfo appServerInfo = new ContainerInfo(appServerContainer);
try { try {


String appServerContextRootStr = isRelative(testContext.getTestClass()) String appServerContextRootStr = isRelative(testContext.getTestClass())
Expand All @@ -80,67 +93,74 @@ private ContainerInfo initializeAppServerInfo(Container appServerContainer, int
return appServerInfo; return appServerInfo;
} }


public void updateTestContextWithAppServerInfo(@Observes BeforeClass event) { @Inject
testContext = testContextProducer.get(); private Instance<ContainerController> containerConrollerInstance;
String appServerQualifier = getAppServerQualifier(testContext.getTestClass());
for (Container container : testContext.getSuiteContext().getArquillianContainers()) { public void startAppServer(@Observes(precedence = -1) BeforeClass event) throws MalformedURLException, InterruptedException, IOException {
if (container.getContainerConfiguration().getContainerName().equals(appServerQualifier)) { if (testContext.isAdapterTest()) {
testContext.setAppServerInfo(initializeAppServerInfo(container)); ContainerController controller = containerConrollerInstance.get();
if (!controller.isStarted(testContext.getAppServerInfo().getQualifier())) {
controller.start(testContext.getAppServerInfo().getQualifier());
} }
} }
// validate app server
if (appServerQualifier != null && testContext.getAppServerInfo() == null) {
throw new RuntimeException(String.format("No app server container matching '%s' was activated. Check if defined and enabled in arquillian.xml.", appServerQualifier));
}
log.info("\n\n" + testContext);
} }


public void startAppServer(@Observes(precedence = -1) BeforeClass event) throws MalformedURLException, InterruptedException, IOException { public void installAdapterLibs(@Observes BeforeDeploy event) {
ContainerController controller = containerController.get(); log.info("BEFORE DEPLOY");
if (testContext.isAdapterTest()) { if (testContext.isAdapterTest()) {
String appServerQualifier = testContext.getAppServerInfo().getQualifier();
if (!controller.isStarted(appServerQualifier)) {
controller.start(appServerQualifier);
}
log.info("\n\n\nAPP SERVER STARTED\n\n\n");
// install adapter libs on JBoss-based container via CLI // install adapter libs on JBoss-based container via CLI
// if (testContext.getAppServerInfo().isJBossBased()) { if (testContext.getAppServerInfo().isJBossBased()) {
installAdapterLibsUsingJBossCLIClient(testContext.getAppServerInfo()); try {
// } installAdapterLibsUsingJBossCLIClient(testContext.getAppServerInfo());
} catch (InterruptedException | IOException ex) {
throw new RuntimeException("Failed to install adapter libs.", ex);
}
}
} }
} }


private void installAdapterLibsUsingJBossCLIClient(ContainerInfo appServerInfo) throws InterruptedException, IOException { private void installAdapterLibsUsingJBossCLIClient(ContainerInfo appServerInfo) throws InterruptedException, IOException {

if (!appServerInfo.isAdapterLibsInstalled()) {
log.info("Installing adapter via CLI client");

if (!appServerInfo.isJBossBased()) {
throw new IllegalArgumentException("App server must be JBoss-based to run jboss-cli-client.");
}


String jbossHomePath = appServerInfo.getProperties().get("jbossHome"); if (!appServerInfo.isJBossBased()) {
throw new IllegalArgumentException("App server must be JBoss-based to run jboss-cli-client.");
}


File bin = new File(jbossHomePath + "/bin"); String jbossHomePath = appServerInfo.getProperties().get("jbossHome");
String command = "java -jar " + jbossHomePath + "/bin/client/jboss-cli-client.jar";
String adapterScript = "adapter-install.cli";
String samlAdapterScript = "adapter-install-saml.cli";
String managementPort = appServerInfo.getProperties().get("managementPort");


String controllerArg = " --controller=localhost:" + managementPort; File bin = new File(jbossHomePath + "/bin");
if (new File(bin, adapterScript).exists()) {
log.info("Installing adapter to app server via cli script"); File clientJar = new File(jbossHomePath + "/bin/client/jboss-cli-client.jar");
execCommand(command + " --connect --file=" + adapterScript + controllerArg, bin); if (!clientJar.exists()) {
} clientJar = new File(jbossHomePath + "/bin/client/jboss-client.jar"); // AS7
if (new File(bin, samlAdapterScript).exists()) { }
log.info("Installing saml adapter to app server via cli script"); if (!clientJar.exists()) {
execCommand(command + " --connect --file=" + samlAdapterScript + controllerArg, bin); throw new IOException("JBoss CLI client JAR not found.");
} }
if (new File(bin, adapterScript).exists() || new File(bin, samlAdapterScript).exists()) {
log.info("Restarting container"); String command = "java -jar " + clientJar.getAbsolutePath();
execCommand(command + " --connect --command=reload" + controllerArg, bin); String adapterScript = "adapter-install.cli";
log.info("Container restarted"); String samlAdapterScript = "adapter-install-saml.cli";
pause(5000); String managementPort = appServerInfo.getProperties().get("managementPort");
LogChecker.checkJBossServerLog(jbossHomePath);
String controllerArg = " --controller=localhost:" + managementPort;
if (new File(bin, adapterScript).exists()) {
log.info("Installing adapter to app server via cli script");
execCommand(command + " --connect --file=" + adapterScript + controllerArg, bin);
}
if (new File(bin, samlAdapterScript).exists()) {
log.info("Installing saml adapter to app server via cli script");
execCommand(command + " --connect --file=" + samlAdapterScript + controllerArg, bin);
}
if (new File(bin, adapterScript).exists() || new File(bin, samlAdapterScript).exists()) {
log.info("Restarting container");
execCommand(command + " --connect --command=reload" + controllerArg, bin);
log.info("Container restarted");
pause(5000);
LogChecker.checkJBossServerLog(jbossHomePath);
}

appServerInfo.setAdapterLibsInstalled(true);
} }
} }


Expand Down
Expand Up @@ -19,7 +19,8 @@
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.LinkedHashSet;
import java.util.Set;


import org.jboss.arquillian.container.spi.Container; import org.jboss.arquillian.container.spi.Container;
import org.jboss.arquillian.container.spi.ContainerRegistry; import org.jboss.arquillian.container.spi.ContainerRegistry;
Expand All @@ -44,79 +45,87 @@
* @author vramik * @author vramik
*/ */
public class AuthServerTestEnricher { public class AuthServerTestEnricher {

protected final Logger log = Logger.getLogger(this.getClass()); protected final Logger log = Logger.getLogger(this.getClass());

@Inject @Inject
private Instance<ContainerRegistry> containerRegistry; private Instance<ContainerRegistry> containerRegistry;

@Inject @Inject
private Instance<ContainerController> containerController; private Instance<ContainerController> containerController;

@Inject @Inject
private Event<StartContainer> startContainerEvent; private Event<StartContainer> startContainerEvent;

private static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container"; private static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container";
private static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow"; private static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow";

private static final String MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY = "migrated.auth.server.container"; private static final String MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY = "migrated.auth.server.container";

@Inject @Inject
@SuiteScoped @SuiteScoped
private InstanceProducer<SuiteContext> suiteContextProducer; private InstanceProducer<SuiteContext> suiteContextProducer;
private SuiteContext suiteContext; private SuiteContext suiteContext;

@Inject @Inject
@ClassScoped @ClassScoped
private InstanceProducer<TestContext> testContextProducer; private InstanceProducer<TestContext> testContextProducer;

public static String getAuthServerQualifier() { public static String getAuthServerQualifier() {
return System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT); return System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT);
} }

public static String getMigratedAuthServerQualifier() { public static String getMigratedAuthServerQualifier() {
return System.getProperty(MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY); // == null if migration not enabled return System.getProperty(MIGRATED_AUTH_SERVER_CONTAINER_PROPERTY); // == null if migration not enabled
} }

public static String getAuthServerContextRoot() { public static String getAuthServerContextRoot() {
return getAuthServerContextRoot(0); return getAuthServerContextRoot(0);
} }

public static String getAuthServerContextRoot(int clusterPortOffset) { public static String getAuthServerContextRoot(int clusterPortOffset) {
int httpPort = Integer.parseInt(System.getProperty("auth.server.http.port")); // property must be set int httpPort = Integer.parseInt(System.getProperty("auth.server.http.port")); // property must be set
int httpsPort = Integer.parseInt(System.getProperty("auth.server.https.port")); // property must be set int httpsPort = Integer.parseInt(System.getProperty("auth.server.https.port")); // property must be set
boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required")); boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required"));

return sslRequired return sslRequired
? "https://localhost:" + (httpsPort + clusterPortOffset) ? "https://localhost:" + (httpsPort + clusterPortOffset)
: "http://localhost:" + (httpPort + clusterPortOffset); : "http://localhost:" + (httpPort + clusterPortOffset);
} }

public void initializeSuiteContext(@Observes(precedence = 2) BeforeSuite event) { public void initializeSuiteContext(@Observes(precedence = 2) BeforeSuite event) {
suiteContext = new SuiteContext(new ArrayList<>(containerRegistry.get().getContainers()));

Set<ContainerInfo> containers = new LinkedHashSet<>();
for (Container c : containerRegistry.get().getContainers()) {
containers.add(new ContainerInfo(c));
}

suiteContext = new SuiteContext(containers);

String authServerQualifier = getAuthServerQualifier(); String authServerQualifier = getAuthServerQualifier();
String migratedAuthServerQualifier = getMigratedAuthServerQualifier(); String migratedAuthServerQualifier = getMigratedAuthServerQualifier();


// init authServerInfo and authServerBackendsInfo // init authServerInfo and authServerBackendsInfo
if (authServerQualifier.startsWith("auth-server-")) { if (authServerQualifier.startsWith("auth-server-")) {

boolean authServerCluster = authServerQualifier.endsWith("-cluster"); boolean authServerCluster = authServerQualifier.endsWith("-cluster");

String authServerType = authServerQualifier.replaceAll("^auth-server-", "").replaceAll("-cluster$", ""); String authServerType = authServerQualifier.replaceAll("^auth-server-", "").replaceAll("-cluster$", "");
String authServerFrontend = authServerCluster String authServerFrontend = authServerCluster
? "auth-server-" + authServerType + "-balancer" // in cluster mode the load-balancer container serves as auth server frontend ? "auth-server-" + authServerType + "-balancer" // in cluster mode the load-balancer container serves as auth server frontend
: authServerQualifier; // single-node mode : authServerQualifier; // single-node mode
String authServerBackend = "auth-server-" + authServerType + "-backend"; String authServerBackend = "auth-server-" + authServerType + "-backend";
int backends = 0; int backends = 0;
for (Container container : suiteContext.getArquillianContainers()) { for (ContainerInfo container : suiteContext.getContainers()) {
// frontend // frontend
if (container.getContainerConfiguration().getContainerName().equals(authServerFrontend)) { if (container.getQualifier().equals(authServerFrontend)) {
suiteContext.setAuthServerInfo(initializeAuthServerInfo(container)); updateWithAuthServerInfo(container);
suiteContext.setAuthServerInfo(container);
} }
// backends // backends
if (container.getContainerConfiguration().getContainerName().startsWith(authServerBackend)) { if (container.getQualifier().startsWith(authServerBackend)) {
suiteContext.getAuthServerBackendsInfo().add(initializeAuthServerInfo(container, ++backends)); updateWithAuthServerInfo(container, ++backends);
suiteContext.getAuthServerBackendsInfo().add(container);
} }
} }


Expand All @@ -127,18 +136,19 @@ public void initializeSuiteContext(@Observes(precedence = 2) BeforeSuite event)
if (authServerCluster && !suiteContext.getAuthServerBackendsInfo().isEmpty()) { if (authServerCluster && !suiteContext.getAuthServerBackendsInfo().isEmpty()) {
throw new RuntimeException(String.format("No cluster backend nodes activated. Containers matching '%sN' need to be enabled in arquillian.xml.", authServerBackend)); throw new RuntimeException(String.format("No cluster backend nodes activated. Containers matching '%sN' need to be enabled in arquillian.xml.", authServerBackend));
} }

} else { } else {
throw new IllegalArgumentException(String.format("Value of %s should start with 'auth-server-' prefix.", AUTH_SERVER_CONTAINER_PROPERTY)); throw new IllegalArgumentException(String.format("Value of %s should start with 'auth-server-' prefix.", AUTH_SERVER_CONTAINER_PROPERTY));
} }

if (migratedAuthServerQualifier != null) { if (migratedAuthServerQualifier != null) {
// init migratedAuthServerInfo // init migratedAuthServerInfo
if (migratedAuthServerQualifier.startsWith("migrated-auth-server-")) { if (migratedAuthServerQualifier.startsWith("migrated-auth-server-")) {
for (Container container : suiteContext.getArquillianContainers()) { for (ContainerInfo container : suiteContext.getContainers()) {
// migrated auth server // migrated auth server
if (container.getContainerConfiguration().getContainerName().equals(migratedAuthServerQualifier)) { if (container.getQualifier().equals(migratedAuthServerQualifier)) {
suiteContext.setMigratedAuthServerInfo(initializeAuthServerInfo(container)); updateWithAuthServerInfo(container);
suiteContext.setMigratedAuthServerInfo(container);
} }
} }
} else { } else {
Expand All @@ -150,49 +160,48 @@ public void initializeSuiteContext(@Observes(precedence = 2) BeforeSuite event)
+ "A container matching '%s' needs to be enabled in arquillian.xml.", migratedAuthServerQualifier)); + "A container matching '%s' needs to be enabled in arquillian.xml.", migratedAuthServerQualifier));
} }
} }

suiteContextProducer.set(suiteContext); suiteContextProducer.set(suiteContext);
log.info("\n\n" + suiteContext); log.info("\n\n" + suiteContext);
} }


public void initializeTestContext(@Observes(precedence = 1) BeforeClass event) { private ContainerInfo updateWithAuthServerInfo(ContainerInfo authServerInfo) {
TestContext testContext = new TestContext(suiteContext, event.getTestClass().getJavaClass()); return updateWithAuthServerInfo(authServerInfo, 0);
testContextProducer.set(testContext);
}

private ContainerInfo initializeAuthServerInfo(Container authServerContainer) {
return initializeAuthServerInfo(authServerContainer, 0);
} }


private ContainerInfo initializeAuthServerInfo(Container authServerContainer, int clusterPortOffset) { private ContainerInfo updateWithAuthServerInfo(ContainerInfo authServerInfo, int clusterPortOffset) {
ContainerInfo authServerInfo = new ContainerInfo(authServerContainer);
try { try {
authServerInfo.setContextRoot(new URL(getAuthServerContextRoot(clusterPortOffset))); authServerInfo.setContextRoot(new URL(getAuthServerContextRoot(clusterPortOffset)));
} catch (MalformedURLException ex) { } catch (MalformedURLException ex) {
throw new IllegalArgumentException(ex); throw new IllegalArgumentException(ex);
} }
return authServerInfo; return authServerInfo;
} }

public void startMigratedContainer(@Observes(precedence = 2) StartSuiteContainers event) { public void startMigratedContainer(@Observes(precedence = 2) StartSuiteContainers event) {
if (suiteContext.isAuthServerMigrationEnabled()) { if (suiteContext.isAuthServerMigrationEnabled()) {
log.info("\n\n### Starting keycloak " + System.getProperty("version", "- previous") + " ###\n"); log.info("\n\n### Starting keycloak " + System.getProperty("version", "- previous") + " ###\n");
startContainerEvent.fire(new StartContainer(suiteContext.getMigratedAuthServerInfo().getArquillianContainer())); startContainerEvent.fire(new StartContainer(suiteContext.getMigratedAuthServerInfo().getArquillianContainer()));
} }
} }

public void stopMigratedContainer(@Observes(precedence = 1) StartSuiteContainers event) { public void stopMigratedContainer(@Observes(precedence = 1) StartSuiteContainers event) {
if (suiteContext.isAuthServerMigrationEnabled()) { if (suiteContext.isAuthServerMigrationEnabled()) {
containerController.get().stop(suiteContext.getAuthServerInfo().getQualifier()); containerController.get().stop(suiteContext.getAuthServerInfo().getQualifier());
} }
} }

public void checkServerLogs(@Observes(precedence = -1) BeforeSuite event) throws IOException, InterruptedException { public void checkServerLogs(@Observes(precedence = -1) BeforeSuite event) throws IOException, InterruptedException {
boolean checkLog = System.getProperty("auth.server.log.check", "true").equals("true"); boolean checkLog = System.getProperty("auth.server.log.check", "true").equals("true");
if (checkLog && suiteContext.getAuthServerInfo().isJBossBased()) { if (checkLog && suiteContext.getAuthServerInfo().isJBossBased()) {
String jbossHomePath = suiteContext.getAuthServerInfo().getProperties().get("jbossHome"); String jbossHomePath = suiteContext.getAuthServerInfo().getProperties().get("jbossHome");
LogChecker.checkJBossServerLog(jbossHomePath); LogChecker.checkJBossServerLog(jbossHomePath);
} }
} }


public void initializeTestContext(@Observes(precedence = 2) BeforeClass event) {
TestContext testContext = new TestContext(suiteContext, event.getTestClass().getJavaClass());
testContextProducer.set(testContext);
}

} }

0 comments on commit 58084d5

Please sign in to comment.