2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2016 - 2017 AT&T
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdnc.sli.resource.dblib;
23 import java.io.PrintWriter;
24 import java.sql.Connection;
25 import java.sql.SQLDataException;
26 import java.sql.SQLException;
27 import java.sql.SQLFeatureNotSupportedException;
28 import java.sql.SQLIntegrityConstraintViolationException;
29 import java.sql.SQLSyntaxErrorException;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.Comparator;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.LinkedList;
36 import java.util.Observable;
37 import java.util.PriorityQueue;
38 import java.util.Properties;
39 import java.util.Queue;
41 import java.util.concurrent.ConcurrentLinkedQueue;
42 import java.util.concurrent.atomic.AtomicBoolean;
44 import javax.sql.DataSource;
45 import javax.sql.rowset.CachedRowSet;
47 import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
48 import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractDBResourceManagerFactory;
49 import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractResourceManagerFactory;
50 import org.openecomp.sdnc.sli.resource.dblib.factory.DBConfigFactory;
51 import org.openecomp.sdnc.sli.resource.dblib.pm.PollingWorker;
52 import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitor;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
58 * @version $Revision: 1.15 $
60 * Author Date Comments
61 * ============== ======== ====================================================
64 public class DBResourceManager implements DataSource, DataAccessor, DBResourceObserver, DbLibService {
65 private static Logger LOGGER = LoggerFactory.getLogger(DBResourceManager.class);
67 transient boolean terminating = false;
68 transient protected long retryInterval = 10000L;
69 transient boolean recoveryMode = true;
71 protected final AtomicBoolean dsSelector = new AtomicBoolean();
73 // Queue<CachedDataSource> dsQueue = new ConcurrentLinkedQueue<CachedDataSource>();
74 Queue<CachedDataSource> dsQueue = new PriorityQueue<CachedDataSource>(4, new Comparator<CachedDataSource>(){
77 public int compare(CachedDataSource left, CachedDataSource right) {
84 } catch (Throwable e) {
91 protected final Set<CachedDataSource> broken = Collections.synchronizedSet(new HashSet<CachedDataSource>());
92 protected final Object monitor = new Object();
93 protected final Properties configProps;
94 protected final Thread worker;
96 protected final long terminationTimeOut;
97 protected final boolean monitorDbResponse;
98 protected final long monitoringInterval;
99 protected final long monitoringInitialDelay;
100 protected final long expectedCompletionTime;
101 protected final long unprocessedFailoverThreshold;
103 public DBResourceManager(Properties props){
104 this.configProps = props;
106 // get retry interval value
107 retryInterval = getLongFromProperties(props, "org.openecomp.dblib.connection.retry", 10000L);
109 // get recovery mode flag
110 recoveryMode = getBooleanFromProperties(props, "org.openecomp.dblib.connection.recovery", true);
113 recoveryMode = false;
114 LOGGER.info("Recovery Mode disabled");
116 // get time out value for thread cleanup
117 terminationTimeOut = getLongFromProperties(props, "org.openecomp.dblib.termination.timeout", 300000L);
118 // get properties for monitoring
119 monitorDbResponse = getBooleanFromProperties(props, "org.openecomp.dblib.connection.monitor", false);
120 monitoringInterval = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.interval", 1000L);
121 monitoringInitialDelay = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.startdelay", 5000L);
122 expectedCompletionTime = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.expectedcompletiontime", 5000L);
123 unprocessedFailoverThreshold = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.unprocessedfailoverthreshold", 3L);
125 // initialize performance monitor
126 PollingWorker.createInistance(props);
128 // initialize recovery thread
129 worker = new RecoveryMgr();
130 worker.setName("DBResourcemanagerWatchThread");
131 worker.setDaemon(true);
135 private void config(Properties ctx) throws Exception {
137 DbConfigPool dbConfig = DBConfigFactory.createConfig(this.configProps);
140 AbstractResourceManagerFactory factory = AbstractDBResourceManagerFactory.getFactory(dbConfig.getType());
141 if(LOGGER.isInfoEnabled()){
142 LOGGER.info("Default DB config is : " + dbConfig.getType());
143 LOGGER.info("Using factory : " + factory.getClass().getName());
145 CachedDataSource[] cachedDS = factory.initDBResourceManager(dbConfig, this);
146 if(cachedDS == null || cachedDS.length == 0) {
147 LOGGER.error("Initialization of CachedDataSources failed. No instance was created.");
148 throw new Exception("Failed to initialize DB Library. No data source was created.");
151 for(int i=0; i<cachedDS.length; i++){
152 if(cachedDS[i] != null && cachedDS[i].isInitialized()){
153 setDataSource(cachedDS[i]);
154 cachedDS[i].setInterval(monitoringInterval);
155 cachedDS[i].setInitialDelay(monitoringInitialDelay);
156 cachedDS[i].setExpectedCompletionTime(expectedCompletionTime);
157 cachedDS[i].setUnprocessedFailoverThreshold(unprocessedFailoverThreshold);
158 cachedDS[i].addObserver(this);
162 } catch(Exception exc){
167 private long getLongFromProperties(Properties props, String property, long defaultValue)
170 long tmpLongValue = defaultValue;
172 value = (String)props.getProperty(property);
174 tmpLongValue = Long.parseLong(value);
176 } catch(NumberFormatException exc) {
177 if(LOGGER.isWarnEnabled()){
178 LOGGER.warn("'"+property+"'=" + value+" is invalid. It should be a numeric value");
180 } catch(Exception exc) {
186 private boolean getBooleanFromProperties(Properties props, String property, boolean defaultValue)
188 boolean tmpValue = defaultValue;
192 value = (String)props.getProperty(property);
194 tmpValue = Boolean.parseBoolean(value);
196 } catch(NumberFormatException exc) {
197 if(LOGGER.isWarnEnabled()){
198 LOGGER.warn("'"+property+"'=" + value+" is invalid. It should be a boolean value");
200 } catch(Exception exc) {
207 public void update(Observable observable, Object data) {
208 // if observable is active and there is a standby available, switch
209 if(observable instanceof SQLExecutionMonitor)
211 SQLExecutionMonitor monitor = (SQLExecutionMonitor)observable;
212 if(monitor.getParent() instanceof CachedDataSource)
214 CachedDataSource dataSource = (CachedDataSource)monitor.getParent();
215 if(dataSource == dsQueue.peek())
217 if(recoveryMode && dsQueue.size() > 1){
218 handleGetConnectionException(dataSource, new Exception(data.toString()));
225 public void testForceRecovery()
227 CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
228 handleGetConnectionException(active, new Exception("test"));
231 class RecoveryMgr extends Thread {
237 Thread.sleep(retryInterval);
238 } catch (InterruptedException e1) { }
239 CachedDataSource brokenSource = null;
241 if (!broken.isEmpty()) {
242 CachedDataSource[] sourceArray = broken.toArray(new CachedDataSource[0]);
243 for (int i = 0; i < sourceArray.length; i++)
245 brokenSource = sourceArray[i];
246 if (brokenSource instanceof TerminatingCachedDataSource)
248 if (resetConnectionPool(brokenSource)) {
249 broken.remove(brokenSource);
250 brokenSource.blockImmediateOffLine();
251 dsQueue.add(brokenSource);
252 LOGGER.info("DataSource <"
253 + brokenSource.getDbConnectionName()
259 } catch (Exception exc) {
260 LOGGER.warn(exc.getMessage());
261 if(brokenSource != null){
263 if(!broken.contains(brokenSource))
264 broken.add(brokenSource);
266 } catch (Exception e1) { }
270 LOGGER.info("DBResourceManager.RecoveryMgr <"+this.toString() +"> terminated." );
273 private boolean resetConnectionPool(CachedDataSource dataSource){
275 return dataSource.testConnection();
276 } catch (Exception exc) {
277 LOGGER.info("DataSource <" + dataSource.getDbConnectionName() + "> resetCache failed with error: "+ exc.getMessage());
284 * @see org.openecomp.dblib.DataAccessor#getData(java.lang.String, java.util.ArrayList)
287 * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#getData(java.lang.String, java.util.ArrayList, java.lang.String)
290 public CachedRowSet getData(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
292 return requestDataWithRecovery(statement, arguments, preferredDS);
294 return requestDataNoRecovery(statement, arguments, preferredDS);
297 private CachedRowSet requestDataWithRecovery(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
298 Throwable lastException = null;
299 CachedDataSource active = null;
301 // test if there are any connection pools available
302 LinkedList<CachedDataSource> sources = new LinkedList<CachedDataSource>(this.dsQueue);
303 if(sources.isEmpty()){
304 LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
305 throw new DBLibException("No active DB connection pools are available in RequestDataWithRecovery call.");
307 if(preferredDS != null && !sources.peek().getDbConnectionName().equals(preferredDS)) {
308 Collections.reverse(sources);
312 // loop through available data sources to retrieve data.
313 while(!sources.isEmpty())
315 active = sources.peek();
317 long time = System.currentTimeMillis();
319 if(!active.isFabric()) {
320 CachedDataSource master = findMaster();
326 sources.remove(active);
327 return active.getData(statement, arguments);
328 } catch(SQLDataException exc){
330 } catch(SQLSyntaxErrorException exc){
332 } catch(SQLIntegrityConstraintViolationException exc){
334 } catch(Throwable exc){
336 String message = exc.getMessage();
337 if(message == null) {
338 if(exc.getCause() != null) {
339 message = exc.getCause().getMessage();
342 message = exc.getClass().getName();
344 LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
345 handleGetConnectionException(active, exc);
347 if(LOGGER.isDebugEnabled()){
348 time = (System.currentTimeMillis() - time);
349 LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
353 if(lastException instanceof SQLException){
354 throw (SQLException)lastException;
356 // repackage the exception
357 // you are here because either you run out of available data sources
358 // or the last exception was not of SQLException type.
359 // repackage the exception
360 if(lastException == null) {
361 throw new DBLibException("The operation timed out while waiting to acquire a new connection." );
363 SQLException exception = new DBLibException(lastException.getMessage());
364 exception.setStackTrace(lastException.getStackTrace());
365 if(lastException.getCause() instanceof SQLException) {
366 throw (SQLException)lastException.getCause();
372 private CachedRowSet requestDataNoRecovery(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
373 if(dsQueue.isEmpty()){
374 LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
375 throw new DBLibException("No active DB connection pools are available in RequestDataNoRecovery call.");
377 CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
378 long time = System.currentTimeMillis();
380 if(!active.isFabric()) {
381 CachedDataSource master = findMaster();
385 return active.getData(statement, arguments);
386 // } catch(SQLDataException exc){
388 } catch(Throwable exc){
389 String message = exc.getMessage();
391 message = exc.getClass().getName();
392 LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
393 if(exc instanceof SQLException)
394 throw (SQLException)exc;
396 DBLibException excptn = new DBLibException(exc.getMessage());
397 excptn.setStackTrace(exc.getStackTrace());
401 if(LOGGER.isDebugEnabled()){
402 time = (System.currentTimeMillis() - time);
403 LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
410 * @see org.openecomp.dblib.DataAccessor#writeData(java.lang.String, java.util.ArrayList)
413 * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#writeData(java.lang.String, java.util.ArrayList, java.lang.String)
416 public boolean writeData(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
417 return writeDataNoRecovery(statement, arguments, preferredDS);
420 CachedDataSource findMaster() {
421 CachedDataSource master = null;
422 CachedDataSource[] dss = this.dsQueue.toArray(new CachedDataSource[0]);
423 for(int i=0; i<dss.length; i++) {
424 if(!dss[i].isSlave()) {
427 dsQueue.remove(master);
434 LOGGER.warn("MASTER not found.");
440 private boolean writeDataNoRecovery(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
441 if(dsQueue.isEmpty()){
442 LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
443 throw new DBLibException("No active DB connection pools are available in RequestDataNoRecovery call.");
446 boolean initialRequest = true;
447 boolean retryAllowed = true;
448 CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
449 long time = System.currentTimeMillis();
450 while(initialRequest) {
451 initialRequest = false;
453 if(!active.isFabric()) {
454 CachedDataSource master = findMaster();
460 return active.writeData(statement, arguments);
461 } catch(Throwable exc){
462 String message = exc.getMessage();
464 message = exc.getClass().getName();
465 LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
466 if(exc instanceof SQLException) {
467 SQLException sqlExc = SQLException.class.cast(exc);
468 // handle read-only exception
469 if(sqlExc.getErrorCode() == 1290 && "HY000".equals(sqlExc.getSQLState())) {
470 LOGGER.warn("retrying due to: " + sqlExc.getMessage());
471 dsQueue.remove(active);
474 retryAllowed = false;
475 initialRequest = true;
479 throw (SQLException)exc;
481 DBLibException excptn = new DBLibException(exc.getMessage());
482 excptn.setStackTrace(exc.getStackTrace());
486 if(LOGGER.isDebugEnabled()){
487 time = (System.currentTimeMillis() - time);
488 LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
495 private void setDataSource(CachedDataSource dataSource) {
496 if(dataSource.testConnection(true)){
497 this.dsQueue.add(dataSource);
499 this.broken.add(dataSource);
503 public Connection getConnection() throws SQLException {
504 Throwable lastException = null;
505 CachedDataSource active = null;
507 if(dsQueue.isEmpty()){
508 throw new DBLibException("No active DB connection pools are available in GetConnection call.");
512 active = dsQueue.peek();
513 CachedDataSource tmpActive = findMaster();
514 if(tmpActive != null) {
517 return active.getConnection();
518 } catch(javax.sql.rowset.spi.SyncFactoryException exc){
519 LOGGER.debug("Free memory (bytes): " + Runtime.getRuntime().freeMemory());
520 LOGGER.warn("CLASSPATH issue. Allowing retry", exc);
522 } catch(Exception exc){
525 handleGetConnectionException(active, exc);
527 if(exc instanceof SQLException)
528 throw (SQLException)exc;
530 DBLibException excptn = new DBLibException(exc.getMessage());
531 excptn.setStackTrace(exc.getStackTrace());
535 } catch (Throwable trwb) {
536 DBLibException excptn = new DBLibException(trwb.getMessage());
537 excptn.setStackTrace(trwb.getStackTrace());
540 if(LOGGER.isDebugEnabled()){
545 if(lastException instanceof SQLException){
546 throw (SQLException)lastException;
548 // repackage the exception
549 if(lastException == null) {
550 throw new DBLibException("The operation timed out while waiting to acquire a new connection." );
552 SQLException exception = new DBLibException(lastException.getMessage());
553 exception.setStackTrace(lastException.getStackTrace());
554 if(lastException.getCause() instanceof SQLException) {
555 // exception.setNextException((SQLException)lastException.getCause());
556 throw (SQLException)lastException.getCause();
562 public Connection getConnection(String username, String password)
563 throws SQLException {
564 CachedDataSource active = null;
566 if(dsQueue.isEmpty()){
567 throw new DBLibException("No active DB connection pools are available in GetConnection call.");
572 active = dsQueue.peek();
573 CachedDataSource tmpActive = findMaster();
574 if(tmpActive != null) {
577 return active.getConnection(username, password);
578 } catch(Throwable exc){
580 handleGetConnectionException(active, exc);
582 if(exc instanceof SQLException)
583 throw (SQLException)exc;
585 DBLibException excptn = new DBLibException(exc.getMessage());
586 excptn.setStackTrace(exc.getStackTrace());
593 throw new DBLibException("No connections available in DBResourceManager in GetConnection call.");
596 private void handleGetConnectionException(CachedDataSource source, Throwable exc) {
598 if(!source.canTakeOffLine())
600 LOGGER.error("Could not switch due to blocking");
604 boolean removed = dsQueue.remove(source);
605 if(!broken.contains(source))
607 if(broken.add(source))
609 LOGGER.warn("DB Recovery: DataSource <" + source.getDbConnectionName() + "> put in the recovery mode. Reason : " + exc.getMessage());
611 LOGGER.warn("Error putting DataSource <" +source.getDbConnectionName()+ "> in recovery mode.");
614 LOGGER.info("DB Recovery: DataSource <" + source.getDbConnectionName() + "> already in recovery queue");
618 if(!dsQueue.isEmpty())
620 LOGGER.warn("DB DataSource <" + dsQueue.peek().getDbConnectionName() + "> became active");
623 } catch (Exception e) {
628 public void cleanUp() {
629 for(Iterator<CachedDataSource> it=dsQueue.iterator();it.hasNext();){
630 CachedDataSource cds = (CachedDataSource)it.next();
636 this.terminating = true;
640 broken.add( new TerminatingCachedDataSource(null));
641 } catch(Exception exc){
642 LOGGER.error("Waiting for Worker to stop", exc);
645 worker.join(terminationTimeOut);
646 LOGGER.info("DBResourceManager.RecoveryMgr <"+worker.toString() +"> termination was successful: " + worker.getState());
647 } catch(Exception exc){
648 LOGGER.error("Waiting for Worker thread to terminate ", exc);
652 public static DBResourceManager create(Properties props) throws Exception {
653 DBResourceManager dbmanager = new DBResourceManager(props);
654 dbmanager.config(props);
658 public PrintWriter getLogWriter() throws SQLException {
659 return ((CachedDataSource)this.dsQueue.peek()).getLogWriter();
662 public int getLoginTimeout() throws SQLException {
663 return ((CachedDataSource)this.dsQueue.peek()).getLoginTimeout();
666 public void setLogWriter(PrintWriter out) throws SQLException {
667 ((CachedDataSource)this.dsQueue.peek()).setLogWriter(out);
670 public void setLoginTimeout(int seconds) throws SQLException {
671 ((CachedDataSource)this.dsQueue.peek()).setLoginTimeout(seconds);
674 public void displayState(){
675 if(LOGGER.isDebugEnabled()){
676 LOGGER.debug("POOLS : Active = "+dsQueue.size() + ";\t Broken = "+broken.size());
677 CachedDataSource current = (CachedDataSource)dsQueue.peek();
678 if(current != null) {
679 LOGGER.debug("POOL : Active name = \'"+current.getDbConnectionName()+ "\'");
685 * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#isActive()
688 public boolean isActive() {
689 return this.dsQueue.size()>0;
692 public String getActiveStatus(){
693 return "Connected: " + dsQueue.size()+"\tIn-recovery: "+broken.size();
696 public String getDBStatus(boolean htmlFormat) {
697 StringBuilder buffer = new StringBuilder();
699 ArrayList<CachedDataSource> list = new ArrayList<CachedDataSource>();
700 list.addAll(dsQueue);
704 buffer.append("<tr class=\"headerRow\"><th id=\"header1\">")
705 .append("Name:").append("</th>");
706 for (int i = 0; i < list.size(); i++) {
707 buffer.append("<th id=\"header").append(2 + i).append("\">");
708 buffer.append(((CachedDataSource) list.get(i)).getDbConnectionName()).append("</th>");
710 buffer.append("</tr>");
712 buffer.append("<tr><td>State:</td>");
713 for (int i = 0; i < list.size(); i++) {
714 if (broken.contains(list.get(i))) {
715 buffer.append("<td>in recovery</td>");
717 if (dsQueue.contains(list.get(i))) {
718 if (dsQueue.peek() == list.get(i))
719 buffer.append("<td>active</td>");
721 buffer.append("<td>standby</td>");
724 buffer.append("</tr>");
727 for (int i = 0; i < list.size(); i++) {
728 buffer.append("Name: ").append(((CachedDataSource) list.get(i)).getDbConnectionName());
729 buffer.append("\tState: ");
730 if (broken.contains(list.get(i))) {
731 buffer.append("in recovery");
733 if (dsQueue.contains(list.get(i))) {
734 if (dsQueue.peek() == list.get(i))
735 buffer.append("active");
737 buffer.append("standby");
744 return buffer.toString();
747 public boolean isWrapperFor(Class<?> iface) throws SQLException {
751 public <T> T unwrap(Class<T> iface) throws SQLException {
756 * @return the monitorDbResponse
758 public final boolean isMonitorDbResponse() {
759 return recoveryMode && monitorDbResponse;
763 CachedDataSource obj = dsQueue.peek();
764 Exception ption = new Exception();
766 for(int i=0; i<5; i++)
768 handleGetConnectionException(obj, ption);
770 } catch(Throwable exc){
771 LOGGER.warn("", exc);
775 public String getPreferredDSName(){
777 return getPreferredDataSourceName(dsSelector);
782 private String getPreferredDataSourceName(AtomicBoolean flipper) {
784 LinkedList<CachedDataSource> snapshot = new LinkedList<CachedDataSource>(dsQueue);
785 if(snapshot.size() > 1){
786 CachedDataSource first = snapshot.getFirst();
787 CachedDataSource last = snapshot.getLast();
789 int delta = first.getMonitor().getPorcessedConnectionsCount() - last.getMonitor().getPorcessedConnectionsCount();
792 } else if(delta > 0) {
795 // check the last value and return !last
796 flipper.getAndSet(!flipper.get());
800 Collections.reverse(snapshot);
802 return snapshot.peek().getDbConnectionName();
805 public java.util.logging.Logger getParentLogger()
806 throws SQLFeatureNotSupportedException {
807 // TODO Auto-generated method stub
811 public String getMasterName() {
813 return getMasterDataSourceName(dsSelector);
819 private String getMasterDataSourceName(AtomicBoolean flipper) {
821 LinkedList<CachedDataSource> snapshot = new LinkedList<CachedDataSource>(dsQueue);
822 if(snapshot.size() > 1){
823 CachedDataSource first = snapshot.getFirst();
824 CachedDataSource last = snapshot.getLast();
826 int delta = first.getMonitor().getPorcessedConnectionsCount() - last.getMonitor().getPorcessedConnectionsCount();
829 } else if(delta > 0) {
832 // check the last value and return !last
833 flipper.getAndSet(!flipper.get());
837 Collections.reverse(snapshot);
839 return snapshot.peek().getDbConnectionName();
843 private void runTest(){
844 Thread producer = null;
846 producer = new ProducerThread("Prod1");
847 producer.setDaemon(true);
850 producer = new ProducerThread("Prod2");
851 producer.setDaemon(true);
854 producer = new ProducerThread("Prod3");
855 producer.setDaemon(true);
858 producer = new ProducerThread("Prod4");
859 producer.setDaemon(true);
862 producer = new ProducerThread("Prod5");
863 producer.setDaemon(true);
866 producer = new ProducerThread("Prod6");
867 producer.setDaemon(true);
870 producer = new ProducerThread("Prod7");
871 producer.setDaemon(true);
874 producer = new ProducerThread("Prod8");
875 producer.setDaemon(true);
878 producer = new ProducerThread("Prod9");
879 producer.setDaemon(true);
882 producer = new ProducerThread("Pro10");
883 producer.setDaemon(true);
888 private final class ProducerThread extends Thread {
889 private ProducerThread(String threadName) {
896 for(int i=0; i<(Integer.MAX_VALUE-1); i++)
899 name = getPreferredDataSourceName(dsSelector);
900 if(name.contains("BACK")){
901 LOGGER.error(this.getName()+": <====== ");
903 LOGGER.error(this.getName()+": ======>");
905 CachedRowSet rs = null;
906 rs = getData("select 1 from dual", new ArrayList<String>(), name);
908 rs = getData("select 1 from dual", new ArrayList<String>(), name);
910 rs = getData("select 1 from dual", new ArrayList<String>(), name);
912 rs = getData("select 1 from dual", new ArrayList<String>(), name);
914 } catch (Exception e) {
920 } catch (InterruptedException e) {