Skip to content

Commit

Permalink
Merge pull request wildfly#17760 from gaol/WFLY-19167
Browse files Browse the repository at this point in the history
[WFLY-19167] war containing JDBC drivers deploys an extra driver
  • Loading branch information
bstansberry authored Apr 15, 2024
2 parents e33eecb + 88a60cd commit 9243568
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@ public void deploy(final DeploymentPhaseContext phaseContext) throws DeploymentU
} else {
DEPLOYER_JDBC_LOGGER.deployingNonCompliantJdbcDriver(driverClass, majorVersion, minorVersion);
}
String driverName = deploymentUnit.getName();
if ((driverName.contains(".") && ! driverName.endsWith(".jar")) || driverNames.size() != 1) {
final String deploymentName = deploymentUnit.getName();
String driverName = deploymentName;
// in case jdbc drivers are placed in war/ear archives
boolean driverWrapped = deploymentName.contains(".") && ! deploymentName.endsWith(".jar");
if (driverWrapped || driverNames.size() != 1) {
driverName += "_" + driverClassName + "_" + majorVersion + "_" + minorVersion;
}
InstalledDriver driverMetadata = new InstalledDriver(driverName, driverClass.getName(), null, null, majorVersion,
Expand All @@ -73,14 +76,13 @@ public void deploy(final DeploymentPhaseContext phaseContext) throws DeploymentU
.addDependency(ConnectorServices.JDBC_DRIVER_REGISTRY_SERVICE, DriverRegistry.class,
driverService.getDriverRegistryServiceInjector()).setInitialMode(Mode.ACTIVE).install();

if (idx == 0 && driverNames.size() != 1) {
if (idx == 0 && driverNames.size() != 1 && !driverWrapped) {
// create short name driver service
driverName = deploymentUnit.getName(); // reset driverName to the deployment unit name
driverMetadata = new InstalledDriver(driverName, driverClass.getName(), null,
driverMetadata = new InstalledDriver(deploymentName, driverClass.getName(), null,
null, majorVersion, minorVersion, compliant);
driverService = new DriverService(driverMetadata, driver);
phaseContext.getServiceTarget()
.addService(ServiceName.JBOSS.append("jdbc-driver", driverName.replaceAll("\\.", "_")), driverService)
.addService(ServiceName.JBOSS.append("jdbc-driver", deploymentName.replaceAll("\\.", "_")), driverService)
.addDependency(ConnectorServices.JDBC_DRIVER_REGISTRY_SERVICE, DriverRegistry.class, driverService.getDriverRegistryServiceInjector())
.setInitialMode(Mode.ACTIVE).install();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -973,4 +973,7 @@ public interface ConnectorLogger extends BasicLogger {

@Message(id = 134, value = "name attribute is mandatory for workmanager element")
XMLStreamException nameAttributeIsMandatory();

@Message(id = 135, value = "The jdbc driver: %s is not installed")
OperationFailedException jdbcDriverNotInstalled(String jdbcDriver);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.jboss.as.connector.subsystems.datasources.Constants.MODULE_SLOT;
import static org.jboss.as.connector.subsystems.datasources.GetDataSourceClassInfoOperationHandler.dsClsInfoNode;

import org.jboss.as.connector.logging.ConnectorLogger;
import org.jboss.as.connector.services.driver.InstalledDriver;
import org.jboss.as.connector.services.driver.registry.DriverRegistry;
import org.jboss.as.connector.util.ConnectorServices;
Expand Down Expand Up @@ -58,6 +59,9 @@ public void execute(final OperationContext context, final ModelNode operation) t
ServiceModuleLoader serviceModuleLoader = (ServiceModuleLoader)registry.getRequiredService(Services.JBOSS_SERVICE_MODULE_LOADER).getValue();
ModelNode result = new ModelNode();
InstalledDriver driver = driverRegistry.getInstalledDriver(name);
if (driver == null) {
throw ConnectorLogger.SUBSYSTEM_DATASOURCES_LOGGER.jdbcDriverNotInstalled(name);
}
ModelNode driverNode = new ModelNode();
driverNode.get(INSTALLED_DRIVER_NAME.getName()).set(driver.getDriverName());
if (driver.isFromDeployment()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.jboss.as.test.integration.jca.datasource;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.as.controller.client.helpers.Operations;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.test.integration.jca.JcaMgmtBase;
import org.jboss.as.test.integration.management.util.MgmtOperationException;
import org.jboss.dmr.ModelNode;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.sql.Driver;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILURE_DESCRIPTION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;

/**
* Test the situation when multiple JDBC drivers inside a war.
*
* @author <a href="mailto:lgao@redhat.com">Lin Gao</a>
*/
@RunWith(Arquillian.class)
@RunAsClient
public class JdbcDriversInWarTestCase extends JcaMgmtBase {

private static final String DEPLOYMENT = "jdbc-in-war.war";

@Deployment(name = DEPLOYMENT)
public static WebArchive jdbcInWarDeployment() throws Exception {
WebArchive war = ShrinkWrap.create(WebArchive.class, DEPLOYMENT);
war.addAsLibrary(ShrinkWrap.create(JavaArchive.class, "testDriver1.jar")
.addClasses(TestDriver.class, DummyDataSource.class, DummyXADataSource.class)
.addAsServiceProviderAndClasses(Driver.class, TestDriver.class));
war.addAsLibrary(ShrinkWrap.create(JavaArchive.class, "testDriver2.jar")
.addClasses(TestDriver2.class, DummyDataSource.class, DummyXADataSource.class)
.addAsServiceProviderAndClasses(Driver.class, TestDriver2.class));
return war;
}

@Test
public void testJdbcDrivers() throws Exception {
String driverName = DEPLOYMENT;
ModelNode address = new ModelNode().add(SUBSYSTEM, "datasources");
String driver1FQCN = driverName + "_" + TestDriver.class.getName() + "_1_0";
ModelNode operation = new ModelNode();
operation.get(OP).set("get-installed-driver");
operation.get(OP_ADDR).set(address);
operation.get("driver-name").set(driver1FQCN);

ModelNode result = executeOperation(operation).asList().get(0);
Assert.assertEquals(driver1FQCN, result.get("driver-name").asString());
Assert.assertEquals(driver1FQCN, result.get("deployment-name").asString());
Assert.assertEquals(TestDriver.class.getName(), result.get("driver-class-name").asString());
Assert.assertEquals(1, result.get("driver-major-version").asInt());
Assert.assertEquals(0, result.get("driver-minor-version").asInt());
Assert.assertFalse(result.get("jdbc-compliant").asBoolean());

String driver2FQCN = driverName + "_" + TestDriver2.class.getName() + "_1_1";
operation.get("driver-name").set(driver2FQCN);
result = executeOperation(operation).asList().get(0);
Assert.assertEquals(driver2FQCN, result.get("driver-name").asString());
Assert.assertEquals(driver2FQCN, result.get("deployment-name").asString());
Assert.assertEquals(TestDriver2.class.getName(), result.get("driver-class-name").asString());
Assert.assertEquals(1, result.get("driver-major-version").asInt());
Assert.assertEquals(1, result.get("driver-minor-version").asInt());
Assert.assertTrue(result.get("jdbc-compliant").asBoolean());

// there should not be a driver named with the deployment name
operation.get("driver-name").set(driverName);
try {
executeOperation(operation);
Assert.fail("should not be here");
} catch (MgmtOperationException e) {
Assert.assertTrue(e.getResult().get(FAILURE_DESCRIPTION).asString().startsWith("WFLYJCA0135"));
}
}

private ModelNode getDatasourceAddress(Datasource datasource) {
ModelNode address = new ModelNode()
.add(SUBSYSTEM, "datasources")
.add("data-source", datasource.getName());
address.protect();
return address;
}

private ModelNode getAddDatasourceOperation(Datasource datasource) {
ModelNode operation = new ModelNode();
operation.get(OP).set(ADD);
operation.get(OP_ADDR).set(getDatasourceAddress(datasource));
operation.get("jndi-name").set(datasource.getJndiName());
operation.get("driver-name").set(datasource.getDriverName());
operation.get("enabled").set(datasource.getEnabled());
operation.get("connection-url").set(datasource.getConnectionUrl());
return operation;
}

private ModelNode getRemoveDatasourceOperation(Datasource ds) {
ModelNode removeOperation = Operations.createRemoveOperation(getDatasourceAddress(ds));
removeOperation.get(ModelDescriptionConstants.OPERATION_HEADERS).get("allow-resource-service-restart")
.set(true);
return removeOperation;
}

@Test
public void testDSWithMutipleDrivers() throws Exception {
String driverName = DEPLOYMENT;
String driver1FQCN = driverName + "_" + TestDriver.class.getName() + "_1_0";
String driver2FQCN = driverName + "_" + TestDriver2.class.getName() + "_1_1";

Datasource ds1FQCN = Datasource.Builder("test-ds1FQCN").connectionUrl("foo").driverName(driver1FQCN).enabled(true)
.jndiName("java:jboss/datasources/test-ds1FQCN").build();
ModelNode addDS1FQCNOperation = getAddDatasourceOperation(ds1FQCN);
try {
ModelNode addDSResult = getManagementClient().getControllerClient().execute(addDS1FQCNOperation);
Assert.assertEquals("success", addDSResult.get("outcome").asString());
} finally {
ModelNode removeDSOperation = getRemoveDatasourceOperation(ds1FQCN);
executeOperation(removeDSOperation);
}

Datasource ds2FQCN = Datasource.Builder("test-ds2FQCN").connectionUrl("foo").driverName(driver2FQCN)
.enabled(true).jndiName("java:jboss/datasources/test-ds2FQCN").build();
ModelNode addDS2FQCNOperation = getAddDatasourceOperation(ds2FQCN);
try {
ModelNode addDSResult = getManagementClient().getControllerClient().execute(addDS2FQCNOperation);
Assert.assertEquals("success", addDSResult.get("outcome").asString());
} finally {
ModelNode removeDSOperation = getRemoveDatasourceOperation(ds2FQCN);
executeOperation(removeDSOperation);
}

}

}

0 comments on commit 9243568

Please sign in to comment.