Sahina Bose has uploaded a new change for review. Change subject: engine: DB persistent scheduler ......................................................................
engine: DB persistent scheduler Adding support for persisting quartz scheduler jobs in the database. Change-Id: I9a34dac95999cb6b3721d201c116fb5f6089bb61 Signed-off-by: Sahina Bose <[email protected]> --- M backend/manager/modules/scheduler/pom.xml A backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzDBImpl.java M backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzImpl.java A backend/manager/modules/scheduler/src/main/resources/ovirt-db-scheduler.properties M backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/BeanType.java M backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/EngineEJBUtilsStrategy.java A packaging/dbscripts/upgrade/03_06_0590_insert_quartz_tables.sql M packaging/services/ovirt-engine/ovirt-engine.xml.in 8 files changed, 385 insertions(+), 2 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/97/36297/1 diff --git a/backend/manager/modules/scheduler/pom.xml b/backend/manager/modules/scheduler/pom.xml index ed37d6b..c794a50 100644 --- a/backend/manager/modules/scheduler/pom.xml +++ b/backend/manager/modules/scheduler/pom.xml @@ -29,9 +29,16 @@ <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> + </dependencies> <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> diff --git a/backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzDBImpl.java b/backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzDBImpl.java new file mode 100644 index 0000000..5fccd12 --- /dev/null +++ b/backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzDBImpl.java @@ -0,0 +1,156 @@ +package org.ovirt.engine.core.utils.timer; + +import java.io.IOException; +import java.util.Date; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.ejb.ConcurrencyManagement; +import javax.ejb.ConcurrencyManagementType; +import javax.ejb.DependsOn; +import javax.ejb.Singleton; +import javax.ejb.Startup; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; + +import org.ovirt.engine.core.utils.ResourceUtils; +import org.ovirt.engine.core.utils.ejb.BeanProxyType; +import org.ovirt.engine.core.utils.ejb.BeanType; +import org.ovirt.engine.core.utils.ejb.EjbUtils; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SchedulerFactory; +import org.quartz.impl.StdSchedulerFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +// Here we use a Singleton bean, names Scheduler. +// The @Startup annotation is to make sure the bean is initialized on startup. +// @ConcurrencyManagement - we use bean managed concurrency: +// Singletons that use bean-managed concurrency allow full concurrent access to all the +// business and timeout methods in the singleton. +// The developer of the singleton is responsible for ensuring that the state of the singleton is synchronized across all clients. +@Singleton(name = "SchedulerDB") +@DependsOn("LockManager") +@Startup +@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) +@ConcurrencyManagement(ConcurrencyManagementType.BEAN) +public class SchedulerUtilQuartzDBImpl extends SchedulerUtilQuartzImpl implements SchedulerUtil { + + // members + private final Logger log = LoggerFactory.getLogger(SchedulerUtilQuartzDBImpl.class); + + private final AtomicLong sequenceNumber = new AtomicLong(Long.MIN_VALUE); + + /** + * This method is called upon the bean creation as part + * of the management Service bean lifecycle. + */ + @Override + @PostConstruct + public void create(){ + setup(); + } + + /* + * retrieving the quartz scheduler from the factory. + */ + @Override + public void setup() { + final String QUARTZ_DB_PROPERTIES = "ovirt-db-scheduler.properties"; + Properties props = null; + try { + props = ResourceUtils.loadProperties(SchedulerUtil.class, QUARTZ_DB_PROPERTIES); + } catch (IOException exception) { + throw new IllegalStateException( + "Can't load properties from resource \"" + + QUARTZ_DB_PROPERTIES + "\".", exception); + } + try { + + SchedulerFactory sf = + new StdSchedulerFactory(props); + sched = sf.getScheduler(); + if (sched != null) { + sched.start(); + } else { + log.error("there is a problem with the underlying Scheduler: null returned"); + } + + + } catch (SchedulerException se) { + log.error("there is a problem with the underlying Scheduler: {}", se.getMessage()); + log.debug("Exception", se); + } + } + + @Override + @PreDestroy + public void teardown() { + try { + if (sched != null) { + sched.shutdown(); + } + } catch (SchedulerException e) { + log.error("Failed to shutdown Quartz service: {}", e.getMessage()); + log.debug("Exception", e); + } + } + + /** + * Returns the single instance of this Class. + * + * @return a SchedulerUtil instance + */ + public static SchedulerUtil getInstance() { + return EjbUtils.findBean(BeanType.SCHEDULERDB, BeanProxyType.LOCAL); + } + + /** + * Halts the Scheduler, and cleans up all resources associated with the Scheduler. The scheduler cannot be + * re-started. + * + * @see org.quartz.Scheduler#shutdown(boolean waitForJobsToComplete) + */ + @Override + public void shutDown() { + try { + sched.shutdown(true); + } catch (SchedulerException se) { + log.error("failed to shut down the scheduler: {}", se.getMessage()); + log.debug("Exception", se); + } + } + + /** + * @return the quartz scheduler wrapped by this SchedulerUtil + */ + @Override + public Scheduler getRawScheduler() { + return sched; + } + + /* + * returns a future date with the given delay. the delay is being calculated + * according to the given Time units + */ + public static Date getFutureDate(long delay, TimeUnit timeUnit) { + if (delay > 0) { + return new Date(new Date().getTime() + TimeUnit.MILLISECONDS.convert(delay, timeUnit)); + } else { + return new Date(); + } + } + + /* + * generate a unique name for the given instance, using a sequence number. + */ + private String generateUniqueNameForInstance(Object instance, String nestedName) { + String name = instance.getClass().getName() + "." + nestedName + "#" + sequenceNumber.incrementAndGet(); + return name; + } + +} diff --git a/backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzImpl.java b/backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzImpl.java index 2d6da99..8515ad2 100644 --- a/backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzImpl.java +++ b/backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtilQuartzImpl.java @@ -63,7 +63,7 @@ // members private final Logger log = LoggerFactory.getLogger(SchedulerUtilQuartzImpl.class); - private Scheduler sched; + protected Scheduler sched; private final AtomicLong sequenceNumber = new AtomicLong(Long.MIN_VALUE); @@ -71,6 +71,7 @@ * This method is called upon the bean creation as part * of the management Service bean lifecycle. */ + @Override @PostConstruct public void create(){ setup(); @@ -330,6 +331,7 @@ * @param newTrigger * - the new Trigger to associate the job with */ + @Override public void rescheduleAJob(String oldTriggerName, String oldTriggerGroup, Trigger newTrigger) { try { if (!sched.isShutdown()) { @@ -435,6 +437,7 @@ /** * @return the quartz scheduler wrapped by this SchedulerUtil */ + @Override public Scheduler getRawScheduler() { return sched; } diff --git a/backend/manager/modules/scheduler/src/main/resources/ovirt-db-scheduler.properties b/backend/manager/modules/scheduler/src/main/resources/ovirt-db-scheduler.properties new file mode 100644 index 0000000..3d328da --- /dev/null +++ b/backend/manager/modules/scheduler/src/main/resources/ovirt-db-scheduler.properties @@ -0,0 +1,9 @@ +org.quartz.scheduler.instanceName=QuartzOvirtDBScheduler +org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT +org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate +org.quartz.jobStore.dataSource=EngineDS +org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool +org.quartz.threadPool.threadCount=100 +org.quartz.jobStore.nonManagedTXDataSource=NMEngineDS +org.quartz.dataSource.EngineDS.jndiURL=java:/ENGINEDataSource +org.quartz.dataSource.NMEngineDS.jndiURL=java:/ENGINEDataSourceNoTx \ No newline at end of file diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/BeanType.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/BeanType.java index 083aebf..e2785c3 100644 --- a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/BeanType.java +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/BeanType.java @@ -6,6 +6,7 @@ public enum BeanType { BACKEND, // Backend bean SCHEDULER, // SchedulerUtil + SCHEDULERDB, // SchedulerUtil VDS_EVENT_LISTENER, LOCK_MANAGER, EVENTQUEUE_MANAGER, diff --git a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/EngineEJBUtilsStrategy.java b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/EngineEJBUtilsStrategy.java index 018e1c9..e5cc24f 100644 --- a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/EngineEJBUtilsStrategy.java +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/ejb/EngineEJBUtilsStrategy.java @@ -15,6 +15,7 @@ protected void addJNDIBeans() { addBeanJNDIName(BeanType.BACKEND, ENGINE_CONTEXT_PREFIX.concat("bll/Backend")); addBeanJNDIName(BeanType.SCHEDULER, ENGINE_CONTEXT_PREFIX.concat("scheduler/Scheduler")); + addBeanJNDIName(BeanType.SCHEDULERDB, ENGINE_CONTEXT_PREFIX.concat("scheduler/SchedulerDB")); addBeanJNDIName(BeanType.VDS_EVENT_LISTENER, ENGINE_CONTEXT_PREFIX.concat("bll/VdsEventListener")); addBeanJNDIName(BeanType.LOCK_MANAGER, ENGINE_CONTEXT_PREFIX.concat("bll/LockManager")); addBeanJNDIName(BeanType.EVENTQUEUE_MANAGER, ENGINE_CONTEXT_PREFIX.concat("bll/EventQueue")); diff --git a/packaging/dbscripts/upgrade/03_06_0590_insert_quartz_tables.sql b/packaging/dbscripts/upgrade/03_06_0590_insert_quartz_tables.sql new file mode 100644 index 0000000..27b5253 --- /dev/null +++ b/packaging/dbscripts/upgrade/03_06_0590_insert_quartz_tables.sql @@ -0,0 +1,184 @@ +-- Thanks to Patrick Lightbody for submitting this... +-- +-- In your Quartz properties file, you'll need to set +-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate + +drop table qrtz_fired_triggers; +DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE QRTZ_SCHEDULER_STATE; +DROP TABLE QRTZ_LOCKS; +drop table qrtz_simple_triggers; +drop table qrtz_cron_triggers; +drop table qrtz_simprop_triggers; +DROP TABLE QRTZ_BLOB_TRIGGERS; +drop table qrtz_triggers; +drop table qrtz_job_details; +drop table qrtz_calendars; + +CREATE TABLE qrtz_job_details + ( + SCHED_NAME VARCHAR(120) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + JOB_CLASS_NAME VARCHAR(250) NOT NULL, + IS_DURABLE BOOL NOT NULL, + IS_NONCONCURRENT BOOL NOT NULL, + IS_UPDATE_DATA BOOL NOT NULL, + REQUESTS_RECOVERY BOOL NOT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) +); + +CREATE TABLE qrtz_triggers + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + NEXT_FIRE_TIME BIGINT NULL, + PREV_FIRE_TIME BIGINT NULL, + PRIORITY INTEGER NULL, + TRIGGER_STATE VARCHAR(16) NOT NULL, + TRIGGER_TYPE VARCHAR(8) NOT NULL, + START_TIME BIGINT NOT NULL, + END_TIME BIGINT NULL, + CALENDAR_NAME VARCHAR(200) NULL, + MISFIRE_INSTR SMALLINT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) +); + +CREATE TABLE qrtz_simple_triggers + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + REPEAT_COUNT BIGINT NOT NULL, + REPEAT_INTERVAL BIGINT NOT NULL, + TIMES_TRIGGERED BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_cron_triggers + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + CRON_EXPRESSION VARCHAR(120) NOT NULL, + TIME_ZONE_ID VARCHAR(80), + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_simprop_triggers + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + STR_PROP_1 VARCHAR(512) NULL, + STR_PROP_2 VARCHAR(512) NULL, + STR_PROP_3 VARCHAR(512) NULL, + INT_PROP_1 INT NULL, + INT_PROP_2 INT NULL, + LONG_PROP_1 BIGINT NULL, + LONG_PROP_2 BIGINT NULL, + DEC_PROP_1 NUMERIC(13,4) NULL, + DEC_PROP_2 NUMERIC(13,4) NULL, + BOOL_PROP_1 BOOL NULL, + BOOL_PROP_2 BOOL NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_blob_triggers + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + BLOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_calendars + ( + SCHED_NAME VARCHAR(120) NOT NULL, + CALENDAR_NAME VARCHAR(200) NOT NULL, + CALENDAR BYTEA NOT NULL, + PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) +); + + +CREATE TABLE qrtz_paused_trigger_grps + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_fired_triggers + ( + SCHED_NAME VARCHAR(120) NOT NULL, + ENTRY_ID VARCHAR(95) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + FIRED_TIME BIGINT NOT NULL, + SCHED_TIME BIGINT NOT NULL, + PRIORITY INTEGER NOT NULL, + STATE VARCHAR(16) NOT NULL, + JOB_NAME VARCHAR(200) NULL, + JOB_GROUP VARCHAR(200) NULL, + IS_NONCONCURRENT BOOL NULL, + REQUESTS_RECOVERY BOOL NULL, + PRIMARY KEY (SCHED_NAME,ENTRY_ID) +); + +CREATE TABLE qrtz_scheduler_state + ( + SCHED_NAME VARCHAR(120) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + LAST_CHECKIN_TIME BIGINT NOT NULL, + CHECKIN_INTERVAL BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) +); + +CREATE TABLE qrtz_locks + ( + SCHED_NAME VARCHAR(120) NOT NULL, + LOCK_NAME VARCHAR(40) NOT NULL, + PRIMARY KEY (SCHED_NAME,LOCK_NAME) +); + +create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP); + +create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME); +create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP); +create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE); +create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); +create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); + +create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME); +create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); +create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); diff --git a/packaging/services/ovirt-engine/ovirt-engine.xml.in b/packaging/services/ovirt-engine/ovirt-engine.xml.in index 3dbb8f3..e62d9f1 100644 --- a/packaging/services/ovirt-engine/ovirt-engine.xml.in +++ b/packaging/services/ovirt-engine/ovirt-engine.xml.in @@ -125,7 +125,6 @@ <logger category="org.springframework.ldap"> <level name="ERROR"/> </logger> - <root-logger> <level name="INFO"/> <handlers> @@ -162,6 +161,29 @@ <check-valid-connection-sql>select 1</check-valid-connection-sql> </validation> </datasource> + + <datasource jndi-name="java:/ENGINEDataSourceNoTx" pool-name="ENGINEDataSourceNoTx" enabled="true" use-ccm="false" jta="false"> + <connection-url><![CDATA[$getstring('ENGINE_DB_URL')]]></connection-url> + <driver>postgresql</driver> + <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation> + <pool> + <min-pool-size>$getinteger('ENGINE_DB_MIN_CONNECTIONS')</min-pool-size> + <max-pool-size>$getinteger('ENGINE_DB_MAX_CONNECTIONS')</max-pool-size> + <prefill>true</prefill> + </pool> + <security> + <user-name><![CDATA[$getstring('ENGINE_DB_USER')]]></user-name> + <password><![CDATA[$getstring('ENGINE_DB_PASSWORD')]]></password> + </security> + <statement> + <prepared-statement-cache-size>100</prepared-statement-cache-size> + <share-prepared-statements/> + </statement> + <validation> + <validate-on-match>true</validate-on-match> + <check-valid-connection-sql>select 1</check-valid-connection-sql> + </validation> + </datasource> <drivers> <driver name="postgresql" module="org.postgresql"> -- To view, visit http://gerrit.ovirt.org/36297 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9a34dac95999cb6b3721d201c116fb5f6089bb61 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Sahina Bose <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
