/**
* Copyright 2015-2016 Red Hat, Inc, and individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.swarm.datasources.runtime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import org.wildfly.swarm.config.datasources.DataSource;
import org.wildfly.swarm.config.runtime.AttributeDocumentation;
import org.wildfly.swarm.datasources.DatasourcesFraction;
import org.wildfly.swarm.spi.api.Customizer;
import org.wildfly.swarm.spi.api.annotations.Configurable;
import org.wildfly.swarm.spi.runtime.annotations.Pre;
/**
* Customizer to attempt auto-detection of JDBC drivers and creation of default datasource, if required.
*
* @author Bob McWhirter
*/
@Pre
@ApplicationScoped
public class DatasourceAndDriverCustomizer implements Customizer {
@Inject
@Any
Instance<DriverInfo> allDrivers;
@Inject
DatasourcesFraction fraction;
private String defaultDatasourceName;
@AttributeDocumentation("Name of the default datasource")
@Configurable("swarm.ds.name")
private String datasourceName = "ExampleDS";
@AttributeDocumentation("Default datasource connection URL")
@Configurable("swarm.ds.connection.url")
private String datasourceConnectionUrl;
@AttributeDocumentation("Default datasource connection user name")
@Configurable("swarm.ds.username")
private String datasourceUserName;
@AttributeDocumentation("Defatul datasource connection password")
@Configurable("swarm.ds.password")
private String datasourcePassword;
@AttributeDocumentation("Defatul datasource JDBC driver name")
@Configurable("swarm.jdbc.driver")
private String driverName;
@Override
public void customize() {
customizeJDBCDrivers();
customizeDefaultDatasource();
}
protected void customizeJDBCDrivers() {
this.allDrivers.forEach(this::attemptInstallation);
}
protected void customizeDefaultDatasource() {
List<DataSource> datasources = this.fraction.subresources().dataSources();
if (datasources.isEmpty()) {
this.defaultDatasourceName = createDefaultDatasource();
} else {
this.defaultDatasourceName = datasources.get(0).getKey();
}
}
private String createDefaultDatasource() {
if (this.fraction.subresources().dataSource(this.datasourceName) != null) {
DatasourcesMessages.MESSAGES.notCreatingDatasourceAlreadyExists(this.datasourceName);
return this.datasourceName;
}
Optional<DriverInfo> driverForDefaultDS = Optional.empty();
if (this.driverName != null) {
driverForDefaultDS = StreamSupport.stream(this.allDrivers.spliterator(), false)
.filter(e -> e.name().equals(this.driverName))
.findFirst();
} else {
List<DriverInfo> installedDrivers = StreamSupport.stream(this.allDrivers.spliterator(), false)
.filter(DriverInfo::isInstalled)
.collect(Collectors.toList());
if (installedDrivers.size() == 1) {
driverForDefaultDS = Optional.of(installedDrivers.get(0));
} else if (installedDrivers.size() > 1) {
List<String> driverNames = installedDrivers.stream().map(e -> e.name()).collect(Collectors.toList());
DatasourcesMessages.MESSAGES.notCreatingDatasourceAmbiguousDrivers(String.join(",", driverNames));
return null;
}
}
if (!driverForDefaultDS.isPresent()) {
DatasourcesMessages.MESSAGES.notCreatingDatasourceMissingDriver();
return null;
}
driverForDefaultDS.get().installDatasource(this.fraction, this.datasourceName, (ds) -> {
if (this.datasourceConnectionUrl != null) {
ds.connectionUrl(this.datasourceConnectionUrl);
}
if (this.datasourceUserName != null) {
ds.userName(this.datasourceUserName);
}
if (this.datasourcePassword != null) {
ds.password(this.datasourcePassword);
}
});
return this.datasourceName;
}
protected void attemptInstallation(DriverInfo info) {
if (info.detect(this.fraction)) {
DatasourcesMessages.MESSAGES.autodetectedJdbcDriver(info.name());
}
}
@Produces
@Dependent
@DefaultDatasource
public String getDatasourceName() {
return this.defaultDatasourceName;
}
}