package org.jboss.weld.tck.wildfly8;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jboss.arquillian.container.spi.event.StartContainer;
import org.jboss.arquillian.core.api.annotation.Observes;
import org.jboss.arquillian.core.spi.EventContext;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.OperationBuilder;
import org.jboss.as.controller.client.helpers.ClientConstants;
import org.jboss.cdi.tck.impl.ConfigurationFactory;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
/**
* Assumptions:
* <ul>
* <li>WildFly 8 managed container adapter</li>
* <li>only one container is used in the same time</li>
* <li>H2 JDBC driver is properly configured</li>
* </ul>
*
* @author Martin Kouba
*/
public class WildFly8EEResourceManager {
private static final Logger logger = Logger.getLogger(WildFly8EEResourceManager.class.getName());
/**
* Observe {@link StartContainer} and check/add required EE resources.
*
* @param eventContext
*/
public void checkResources(@Observes EventContext<StartContainer> eventContext) {
try {
// First start the container
eventContext.proceed();
// Then check resources
ModelControllerClient client = ModelControllerClient.Factory.create("localhost", 9990);
WildFlyMessaging messaging = WildFlyMessaging.get(client);
if (messaging != null) {
messaging.checkJmsQueue(client);
messaging.checkJmsTopic(client);
} else {
/*
* JMS subsystem may not be installed (e.g. when debugging against standalone.xml) If this happens, do not attempt to install Queue/Topic as
* that always fails
*/
logger.log(Level.WARNING, "JMS subsystem not installed. Skipping test Queue/Topic installation.");
}
checkTestDataSource(client);
checkEarSubdeploymentsIsolation(client);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Check JMS topic and try to create one if it does not exist.
*
* @param client
* @throws IOException
*/
private void checkJmsTopic(ModelControllerClient client) throws IOException {
ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-resource");
request.get("recursive").set(true);
ModelNode address = request.get(ClientConstants.OP_ADDR);
address.add("subsystem", "messaging");
address.add("hornetq-server", "default");
address.add("jms-topic", "testTopic");
ModelNode response = client.execute(new OperationBuilder(request).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
request = new ModelNode();
request.get(ClientConstants.OP).set("add");
address = request.get(ClientConstants.OP_ADDR);
address.add("subsystem", "messaging");
address.add("hornetq-server", "default");
address.add("jms-topic", "testTopic");
ModelNode entries = request.get("entries");
entries.add("topic/test");
entries.add("java:jboss/exported/jms/topic/test");
response = client.execute(new OperationBuilder(request).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
throw new RuntimeException("Test JMS topic was not found and could not be created automatically: " + response);
}
logger.log(Level.INFO, "Test JMS topic added");
}
}
/**
* Check JMS queue and try to create one if it does not exist.
*
* @param client
* @throws IOException
*/
private void checkJmsQueue(ModelControllerClient client) throws IOException {
ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-resource");
request.get("recursive").set(true);
ModelNode address = request.get(ClientConstants.OP_ADDR);
address.add("subsystem", "messaging");
address.add("hornetq-server", "default");
address.add("jms-queue", "testQueue");
ModelNode response = client.execute(new OperationBuilder(request).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
request = new ModelNode();
request.get(ClientConstants.OP).set("add");
address = request.get(ClientConstants.OP_ADDR);
address.add("subsystem", "messaging");
address.add("hornetq-server", "default");
address.add("jms-queue", "testQueue");
ModelNode entries = request.get("entries");
entries.add("queue/test");
entries.add("java:jboss/exported/jms/queue/test");
response = client.execute(new OperationBuilder(request).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
throw new RuntimeException("Test JMS queue was not found and could not be created automatically: " + response);
}
logger.log(Level.INFO, "Test JMS queue added");
}
}
/**
* Check test data source and try to create one if it does not exist.
*
* @param client
* @throws IOException
*/
private void checkTestDataSource(ModelControllerClient client) throws IOException {
// JNDI name has to be set via properties at the moment
String testDataSourceJndiName = ConfigurationFactory.get().getTestDataSource();
ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-resource");
request.get("recursive").set("true");
request.get(ClientConstants.OP_ADDR).get("subsystem").set("datasources");
ModelNode response = client.execute(new OperationBuilder(request).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
throw new RuntimeException("Unable to read existing data sources: " + response);
}
boolean found = false;
if (response.get("result").hasDefined("data-source")) {
for (Property dataSource : response.get("result").get("data-source").asPropertyList()) {
if (dataSource.getValue().get("jndi-name").asString().equals(testDataSourceJndiName)) {
logger.log(Level.INFO, "Test data source found");
found = true;
}
}
}
if (!found) {
String poolName = "TestTckDS";
request = new ModelNode();
request.get(ClientConstants.OP).set("add");
ModelNode address = request.get(ClientConstants.OP_ADDR);
address.add("subsystem", "datasources");
address.add("data-source", poolName);
request.get("jndi-name").set(testDataSourceJndiName);
request.get("pool-name").set(poolName);
request.get("enabled").set("true");
request.get("use-java-context").set("true");
request.get("connection-url").set("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
request.get("driver-name").set("h2");
request.get("security").get("user-name").set("sa");
request.get("security").get("password").set("sa");
response = client.execute(new OperationBuilder(request).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
throw new RuntimeException("Test data source was not found and could not be created automatically: " + response);
}
// As of AS7 7.1 we have to enable DS
ModelNode enableRequest = new ModelNode();
enableRequest.get(ClientConstants.OP).set("enable");
enableRequest.get("address").get("subsystem").set("datasources");
enableRequest.get("address").get("data-source").set(poolName);
ModelNode enableResult = client.execute(new OperationBuilder(enableRequest).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
throw new RuntimeException("Test data source could not be enabled automatically: " + enableResult);
}
logger.log(Level.INFO, "Test data source added: {0}", testDataSourceJndiName);
}
}
private void checkEarSubdeploymentsIsolation(ModelControllerClient client) throws IOException {
ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-attribute");
request.get("name").set("ear-subdeployments-isolated");
request.get(ClientConstants.OP_ADDR).get("subsystem").set("ee");
ModelNode response = client.execute(new OperationBuilder(request).build());
boolean isolated = response.get(ClientConstants.RESULT).asBoolean();
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
throw new RuntimeException("Unable to read ear-subdeployments-isolated attribute: " + response);
}
if (!isolated) {
ModelNode writeRequest = new ModelNode();
writeRequest.get(ClientConstants.OP).set("write-attribute");
writeRequest.get("name").set("ear-subdeployments-isolated");
writeRequest.get("value").set("true");
writeRequest.get(ClientConstants.OP_ADDR).get("subsystem").set("ee");
ModelNode writeResponse = client.execute(new OperationBuilder(writeRequest).build());
if (!response.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
throw new RuntimeException("Unable to write ear-subdeployments-isolated attribute: " + writeResponse);
}
}
}
}