/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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.kie.workbench.common.screens.datasource.management.backend; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import org.kie.workbench.common.screens.datasource.management.backend.core.DataSourceDefDeployer; import org.kie.workbench.common.screens.datasource.management.backend.core.DataSourceRuntimeManager; import org.kie.workbench.common.screens.datasource.management.backend.core.DataSourceSettings; import org.kie.workbench.common.screens.datasource.management.backend.core.DefaultDriverInitializer; import org.kie.workbench.common.screens.datasource.management.backend.core.DriverDefDeployer; import org.kie.workbench.common.screens.datasource.management.backend.service.DefChangeHandler; import org.kie.workbench.common.screens.datasource.management.backend.service.DefResourceChangeObserver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; import static org.kie.workbench.common.screens.datasource.management.backend.core.DataSourceSettings.*; import static org.kie.workbench.common.screens.datasource.management.util.ServiceUtil.*; /** * Initializations required by the data sources management system. */ @ApplicationScoped @Startup(StartupType.BOOTSTRAP) public class DataSourceManagementBootstrap { private static final Logger logger = LoggerFactory.getLogger(DataSourceManagementBootstrap.class); public static final String DEPLOYMENTS_INITIALIZATION_RETRIES = DATASOURCE_MANAGEMENT_PREFIX + ".deploymentsInitializationRetries"; public static final String DEPLOYMENTS_INITIALIZATION_DELAY = DATASOURCE_MANAGEMENT_PREFIX + ".deploymentsInitializationDelay"; public static final String DEF_CHANGE_HANDLER_BEAN = DATASOURCE_MANAGEMENT_PREFIX + ".DefChangeHandler"; private DataSourceRuntimeManager dataSourceRuntimeManager; private DataSourceDefDeployer dataSourceDefDeployer; private DriverDefDeployer driverDefDeployer; private DefaultDriverInitializer driverInitializer; private DefResourceChangeObserver defResourceChangeObserver; private BeanManager beanManager; protected long deploymentsInitializationRetries = 20; protected long deploymentsInitializationDelay = 30000; protected ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); public DataSourceManagementBootstrap() { //Empty constructor for Weld proxying } @Inject public DataSourceManagementBootstrap(DataSourceRuntimeManager dataSourceRuntimeManager, DataSourceDefDeployer dataSourceDefDeployer, DriverDefDeployer driverDefDeployer, DefaultDriverInitializer driverInitializer, DefResourceChangeObserver defResourceChangeObserver, BeanManager beanManager) { this.dataSourceRuntimeManager = dataSourceRuntimeManager; this.dataSourceDefDeployer = dataSourceDefDeployer; this.driverDefDeployer = driverDefDeployer; this.driverInitializer = driverInitializer; this.defResourceChangeObserver = defResourceChangeObserver; this.beanManager = beanManager; } @PostConstruct public void init() { initializeConfigParams(); initializeDefChangeHandler(); driverInitializer.initializeDefaultDrivers(); scheduler.schedule(getInitializeDeploymentsTask(), deploymentsInitializationDelay, TimeUnit.MILLISECONDS); } @PreDestroy public void destroy() { if (scheduler != null && !scheduler.isShutdown()) { try { scheduler.shutdownNow(); } catch (Exception e) { //uncommon case logger.warn("DataSourceManagementBootstrap termination error: " + e.getMessage(), e); } } } /** * Ensures that data sources and drivers definitions are properly deployed when the server is restarted. */ protected void initializeDeployments() { driverDefDeployer.deployGlobalDefs(); dataSourceDefDeployer.deployGlobalDefs(); } /** * Initializes the data source and drivers definitions change handler when configured. */ protected void initializeDefChangeHandler() { logger.info("Initializing data source definitions change handler"); String defChangeHandlerName = getManagedProperty(DataSourceSettings.getInstance().getProperties(), DEF_CHANGE_HANDLER_BEAN); if (defChangeHandlerName != null) { try { defResourceChangeObserver.setDefChangeHandler(getDefChangeHandler(defChangeHandlerName)); } catch (Exception e) { logger.error("An error was produced during defChangeHandler initialization: " + defChangeHandlerName, e); } } else { logger.info("defChangeHandler was not set"); } } protected void initializeConfigParams() { String value = null; try { value = getManagedProperty(DataSourceSettings.getInstance().getProperties(), DEPLOYMENTS_INITIALIZATION_RETRIES, Long.toString(deploymentsInitializationRetries)); deploymentsInitializationRetries = Long.parseLong(value); } catch (NumberFormatException e) { logger.warn("Wrong integer value: " + value + " was set for property: " + DEPLOYMENTS_INITIALIZATION_RETRIES + " The by default value: " + deploymentsInitializationRetries + " will be used instead."); } try { value = getManagedProperty(DataSourceSettings.getInstance().getProperties(), DEPLOYMENTS_INITIALIZATION_DELAY, Long.toString(deploymentsInitializationDelay)); deploymentsInitializationDelay = Long.parseLong(value); } catch (NumberFormatException e) { logger.warn("Wrong integer value: " + value + " was set for property: " + DEPLOYMENTS_INITIALIZATION_DELAY + " The by default value: " + deploymentsInitializationDelay + " will be used instead."); } } protected Runnable getInitializeDeploymentsTask() { return () -> { try { logger.debug("Initialize deployments task started."); deploymentsInitializationRetries--; dataSourceRuntimeManager.hasStarted(); initializeDeployments(); logger.info("Initialize deployments task finished successfully."); scheduler.shutdown(); } catch (Exception e) { logger.warn("Initialize deployments task finished with errors: " + e.getMessage()); if (deploymentsInitializationRetries > 0) { logger.warn("Startup drivers and datasources initialization will be retried again in: " + deploymentsInitializationDelay + " " + TimeUnit.MILLISECONDS.name() + "(" + deploymentsInitializationRetries + " attempts left)"); scheduler.schedule(getInitializeDeploymentsTask(), deploymentsInitializationDelay, TimeUnit.MILLISECONDS); } else { logger.error("No more retries are available, some drivers or datasources might not work properly. " + e.getMessage(), e); scheduler.shutdown(); } } }; } /** * for testing purposes. */ protected DefChangeHandler getDefChangeHandler(String defChangeHandlerName) { return (DefChangeHandler) getManagedBean(beanManager, defChangeHandlerName); } }