use of io.quarkus.datasource.deployment.spi.DevServicesDatasourceProviderBuildItem in project quarkus by quarkusio.
the class DerbyDevServicesProcessor method setupDerby.
@BuildStep
DevServicesDatasourceProviderBuildItem setupDerby() {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.DERBY, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password, Optional<String> datasourceName, Optional<String> imageName, Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties, OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
try {
int port = fixedExposedPort.isPresent() ? fixedExposedPort.getAsInt() : 1527 + (launchMode == LaunchMode.TEST ? 0 : 1);
NetworkServerControl server = new NetworkServerControl(InetAddress.getByName("localhost"), port);
server.start(new PrintWriter(System.out));
for (int i = 1; i <= NUMBER_OF_PINGS; i++) {
try {
LOG.info("Attempt " + i + " to see if Dev Services for Derby started");
server.ping();
break;
} catch (Exception ex) {
if (i == NUMBER_OF_PINGS) {
LOG.error("Dev Services for Derby failed to start", ex);
throw ex;
}
try {
Thread.sleep(SLEEP_BETWEEN_PINGS);
} catch (InterruptedException ignore) {
}
}
}
LOG.info("Dev Services for Derby started.");
StringBuilder additionalArgs = new StringBuilder();
for (Map.Entry<String, String> i : additionalJdbcUrlProperties.entrySet()) {
additionalArgs.append(";");
additionalArgs.append(i.getKey());
additionalArgs.append("=");
additionalArgs.append(i.getValue());
}
return new RunningDevServicesDatasource(null, "jdbc:derby://localhost:" + port + "/memory:" + datasourceName.orElse("quarkus") + ";create=true" + additionalArgs.toString(), null, null, new Closeable() {
@Override
public void close() throws IOException {
try {
NetworkServerControl server = new NetworkServerControl(InetAddress.getByName("localhost"), port);
server.shutdown();
LOG.info("Dev Services for Derby shut down");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
} catch (Exception throwable) {
throw new RuntimeException(throwable);
}
}
@Override
public boolean isDockerRequired() {
return false;
}
});
}
use of io.quarkus.datasource.deployment.spi.DevServicesDatasourceProviderBuildItem in project quarkus by quarkusio.
the class DevServicesDatasourceProcessor method launchDatabases.
@BuildStep(onlyIfNot = IsNormal.class, onlyIf = GlobalDevServicesConfig.Enabled.class)
DevServicesDatasourceResultBuildItem launchDatabases(CurateOutcomeBuildItem curateOutcomeBuildItem, DockerStatusBuildItem dockerStatusBuildItem, List<DefaultDataSourceDbKindBuildItem> installedDrivers, List<DevServicesDatasourceProviderBuildItem> devDBProviders, DataSourcesBuildTimeConfig dataSourceBuildTimeConfig, LaunchModeBuildItem launchMode, List<DevServicesDatasourceConfigurationHandlerBuildItem> configurationHandlerBuildItems, BuildProducer<DevServicesResultBuildItem> devServicesResultBuildItemBuildProducer, Optional<ConsoleInstalledBuildItem> consoleInstalledBuildItem, CuratedApplicationShutdownBuildItem closeBuildItem, LoggingSetupBuildItem loggingSetupBuildItem, GlobalDevServicesConfig globalDevServicesConfig) {
// if not and the DB's have already started we just return
if (databases != null) {
boolean restartRequired = false;
if (!restartRequired) {
for (Map.Entry<String, String> entry : cachedProperties.entrySet()) {
if (!Objects.equals(entry.getValue(), trim(ConfigProvider.getConfig().getOptionalValue(entry.getKey(), String.class).orElse(null)))) {
restartRequired = true;
break;
}
}
}
if (!restartRequired) {
// devservices properties may have been added
for (var name : ConfigProvider.getConfig().getPropertyNames()) {
if (name.startsWith("quarkus.datasource.") && name.contains(".devservices.") && !cachedProperties.containsKey(name)) {
restartRequired = true;
break;
}
}
}
if (!restartRequired) {
for (RunningDevService database : databases) {
devServicesResultBuildItemBuildProducer.produce(database.toBuildItem());
}
// keep the previous behaviour of producing DevServicesDatasourceResultBuildItem only when the devservice first starts.
return null;
}
for (Closeable i : databases) {
try {
i.close();
} catch (Throwable e) {
log.error("Failed to stop database", e);
}
}
databases = null;
cachedProperties = null;
}
DevServicesDatasourceResultBuildItem.DbResult defaultResult;
Map<String, DevServicesDatasourceResultBuildItem.DbResult> namedResults = new HashMap<>();
// now we need to figure out if we need to launch some databases
// note that because we run in dev and test mode only we know the runtime
// config at build time, as they both execute in the same JVM
// to keep things simpler for now we are only going to support this for the default datasource
// support for named datasources will come later
Map<String, String> propertiesMap = new HashMap<>();
List<RunningDevService> runningDevServices = new ArrayList<>();
Map<String, List<DevServicesDatasourceConfigurationHandlerBuildItem>> configHandlersByDbType = configurationHandlerBuildItems.stream().collect(Collectors.toMap(DevServicesDatasourceConfigurationHandlerBuildItem::getDbKind, Collections::singletonList, (configurationHandlerBuildItems1, configurationHandlerBuildItems2) -> {
List<DevServicesDatasourceConfigurationHandlerBuildItem> ret = new ArrayList<>();
ret.addAll(configurationHandlerBuildItems1);
ret.addAll(configurationHandlerBuildItems2);
return ret;
}));
Map<String, DevServicesDatasourceProvider> devDBProviderMap = devDBProviders.stream().collect(Collectors.toMap(DevServicesDatasourceProviderBuildItem::getDatabase, DevServicesDatasourceProviderBuildItem::getDevServicesProvider));
RunningDevService defaultDevService = startDevDb(null, curateOutcomeBuildItem, installedDrivers, !dataSourceBuildTimeConfig.namedDataSources.isEmpty(), devDBProviderMap, dataSourceBuildTimeConfig.defaultDataSource, configHandlersByDbType, propertiesMap, dockerStatusBuildItem, launchMode.getLaunchMode(), consoleInstalledBuildItem, loggingSetupBuildItem, globalDevServicesConfig);
if (defaultDevService != null) {
runningDevServices.add(defaultDevService);
}
defaultResult = toDbResult(defaultDevService);
for (Map.Entry<String, DataSourceBuildTimeConfig> entry : dataSourceBuildTimeConfig.namedDataSources.entrySet()) {
RunningDevService namedDevService = startDevDb(entry.getKey(), curateOutcomeBuildItem, installedDrivers, true, devDBProviderMap, entry.getValue(), configHandlersByDbType, propertiesMap, dockerStatusBuildItem, launchMode.getLaunchMode(), consoleInstalledBuildItem, loggingSetupBuildItem, globalDevServicesConfig);
if (namedDevService != null) {
runningDevServices.add(namedDevService);
namedResults.put(entry.getKey(), toDbResult(namedDevService));
}
}
if (first) {
first = false;
Runnable closeTask = new Runnable() {
@Override
public void run() {
if (databases != null) {
for (Closeable i : databases) {
try {
i.close();
} catch (Throwable t) {
log.error("Failed to stop database", t);
}
}
}
first = true;
databases = null;
cachedProperties = null;
}
};
closeBuildItem.addCloseTask(closeTask, true);
}
databases = runningDevServices;
cachedProperties = propertiesMap;
for (RunningDevService database : databases) {
devServicesResultBuildItemBuildProducer.produce(database.toBuildItem());
}
return new DevServicesDatasourceResultBuildItem(defaultResult, namedResults);
}
use of io.quarkus.datasource.deployment.spi.DevServicesDatasourceProviderBuildItem in project quarkus by quarkusio.
the class H2DevServicesProcessor method setupH2.
@BuildStep
DevServicesDatasourceProviderBuildItem setupH2() {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.H2, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password, Optional<String> datasourceName, Optional<String> imageName, Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties, OptionalInt port, LaunchMode launchMode, Optional<Duration> startupTimeout) {
try {
final Server tcpServer = Server.createTcpServer("-tcpPort", port.isPresent() ? String.valueOf(port.getAsInt()) : "0", "-ifNotExists");
tcpServer.start();
StringBuilder additionalArgs = new StringBuilder();
for (Map.Entry<String, String> i : additionalJdbcUrlProperties.entrySet()) {
additionalArgs.append(";");
additionalArgs.append(i.getKey());
additionalArgs.append("=");
additionalArgs.append(i.getValue());
}
LOG.info("Dev Services for H2 started.");
String connectionUrl = "jdbc:h2:tcp://localhost:" + tcpServer.getPort() + "/mem:" + datasourceName.orElse("default") + ";DB_CLOSE_DELAY=-1" + additionalArgs.toString();
return new RunningDevServicesDatasource(null, connectionUrl, "sa", "sa", new Closeable() {
@Override
public void close() throws IOException {
// (perhaps we failed to start?)
if (tcpServer.isRunning(false)) {
// make sure the DB is removed on close
try (Connection connection = DriverManager.getConnection(connectionUrl, "sa", "sa")) {
try (Statement statement = connection.createStatement()) {
statement.execute("SET DB_CLOSE_DELAY 0");
}
} catch (SQLException t) {
t.printStackTrace();
}
tcpServer.stop();
LOG.info("Dev Services for H2 shut down; server status: " + tcpServer.getStatus());
} else {
LOG.info("Dev Services for H2 was NOT shut down as it appears it was down already; server status: " + tcpServer.getStatus());
}
}
});
} catch (SQLException throwables) {
throw new RuntimeException(throwables);
}
}
@Override
public boolean isDockerRequired() {
return false;
}
});
}
Aggregations