1 22 package org.jboss.resource.connectionmanager; 23 24 import java.security.AccessController ; 25 import java.security.PrivilegedAction ; 26 import java.util.Iterator ; 27 import java.util.Map ; 28 29 import javax.management.Notification ; 30 import javax.management.NotificationFilter ; 31 import javax.management.NotificationListener ; 32 import javax.management.ObjectName ; 33 import javax.resource.ResourceException ; 34 import javax.resource.spi.ConnectionRequestInfo ; 35 import javax.resource.spi.ManagedConnectionFactory ; 36 import javax.security.auth.Subject ; 37 import javax.transaction.Transaction ; 38 import javax.transaction.TransactionManager ; 39 40 import org.jboss.deployment.DeploymentException; 41 import org.jboss.logging.Logger; 42 import org.jboss.mx.util.JMXExceptionDecoder; 43 import org.jboss.resource.JBossResourceException; 44 import org.jboss.resource.connectionmanager.InternalManagedConnectionPool.PoolParams; 45 import org.jboss.resource.statistic.JBossStatistics; 46 import org.jboss.resource.statistic.StatisticsReporter; 47 import org.jboss.resource.statistic.formatter.StatisticsFormatter; 48 import org.jboss.resource.statistic.pool.JBossDefaultSubPoolStatisticFormatter; 49 import org.jboss.resource.statistic.pool.JBossManagedConnectionPoolStatistics; 50 import org.jboss.resource.statistic.pool.JBossSubPoolStatistics; 51 import org.jboss.resource.statistic.pool.ManagedConnectionPoolStatistics; 52 import org.jboss.system.ServiceMBeanSupport; 53 import org.jboss.tm.TransactionLocal; 54 55 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; 56 57 71 public class JBossManagedConnectionPool extends ServiceMBeanSupport 72 implements JBossManagedConnectionPoolMBean, NotificationListener 73 { 74 75 static Logger log = Logger.getLogger(JBossManagedConnectionPool.class); 76 77 78 private ObjectName managedConnectionFactoryName; 79 80 81 private String criteria; 82 83 84 private ManagedConnectionPool poolingStrategy; 85 86 87 private final InternalManagedConnectionPool.PoolParams poolParams = new InternalManagedConnectionPool.PoolParams(); 88 89 90 private boolean noTxSeparatePools; 91 92 95 private String statisticsFormatter; 96 97 private String poolJndiName; 98 99 public JBossManagedConnectionPool() 100 { 101 } 102 103 public Object listFormatttedSubPoolStatistics(String formatClassName) 104 { 105 final JBossStatistics stats = (JBossStatistics)listStatistics(); 106 final ClassLoader cl = Thread.currentThread().getContextClassLoader(); 107 Class clazz; 108 StatisticsFormatter formatter = null; 109 110 try 111 { 112 clazz = cl.loadClass(formatClassName); 113 formatter = (StatisticsFormatter)clazz.newInstance(); 114 } 115 catch (Exception e) 116 { 117 log.warn("warn: statistics formatter not found, setting to " + statisticsFormatter); 118 formatter = new JBossDefaultSubPoolStatisticFormatter(); 119 120 } 121 122 return formatter.formatStatistics(stats); 123 } 124 125 public Object listFormattedSubPoolStatistics(){ 126 127 Object formatted = listFormatttedSubPoolStatistics(statisticsFormatter); 128 return formatted; 129 } 130 131 public Object listStatistics() 132 { 133 ManagedConnectionPoolStatistics stats = null; 134 135 if (poolingStrategy instanceof StatisticsReporter) 136 { 137 138 StatisticsReporter reporter = (StatisticsReporter) poolingStrategy; 139 stats = (ManagedConnectionPoolStatistics)reporter.listStatistics(); 140 stats.setCriteria(getCriteria()); 141 stats.setName(getManagedConnectionFactoryName().toString()); 142 143 } 144 145 return stats; 146 } 147 148 public ManagedConnectionPool getManagedConnectionPool() 149 { 150 return poolingStrategy; 151 } 152 153 public ObjectName getManagedConnectionFactoryName() 154 { 155 return managedConnectionFactoryName; 156 } 157 158 public void setManagedConnectionFactoryName(ObjectName newManagedConnectionFactoryName) 159 { 160 this.managedConnectionFactoryName = newManagedConnectionFactoryName; 161 } 162 163 public long getAvailableConnectionCount() 164 { 165 return (poolingStrategy == null) ? 0 : poolingStrategy.getAvailableConnectionCount(); 166 } 167 168 public long getMaxConnectionsInUseCount() 169 { 170 return (poolingStrategy == null) ? 0 : poolingStrategy.getMaxConnectionsInUseCount(); 171 } 172 173 public long getInUseConnectionCount () 174 { 175 return (poolingStrategy == null) ? 0 : poolingStrategy.getInUseConnectionCount(); 176 } 177 178 public int getMinSize() 179 { 180 return poolParams.minSize; 181 } 182 183 public void setMinSize(int newMinSize) 184 { 185 poolParams.minSize = newMinSize; 186 } 187 188 public int getMaxSize() 189 { 190 return poolParams.maxSize; 191 } 192 193 public void setMaxSize(int newMaxSize) 194 { 195 poolParams.maxSize = newMaxSize; 196 } 197 198 public int getBlockingTimeoutMillis() 199 { 200 return poolParams.blockingTimeout; 201 } 202 203 public void setBlockingTimeoutMillis(int newBlockingTimeout) 204 { 205 poolParams.blockingTimeout = newBlockingTimeout; 206 } 207 208 public long getIdleTimeoutMinutes() 209 { 210 return poolParams.idleTimeout / (1000 * 60); 211 } 212 213 public void setIdleTimeoutMinutes(long newIdleTimeoutMinutes) 214 { 215 poolParams.idleTimeout = newIdleTimeoutMinutes * 1000 * 60; 216 } 217 218 223 public long getIdleTimeout() 224 { 225 return poolParams.idleTimeout; 226 } 227 228 233 public void setIdleTimeout(long newIdleTimeout) 234 { 235 poolParams.idleTimeout = newIdleTimeout; 236 } 237 238 public String getCriteria() 239 { 240 return criteria; 241 } 242 243 public void setCriteria(String newCriteria) 244 { 245 this.criteria = newCriteria; 246 } 247 248 public boolean getNoTxSeparatePools() 249 { 250 return noTxSeparatePools; 251 } 252 253 public void setNoTxSeparatePools(boolean value) 254 { 255 this.noTxSeparatePools = value; 256 } 257 258 public boolean getPreFill(){ 259 260 return poolParams.prefill; 261 262 } 263 264 public void setPreFill(boolean prefill){ 265 266 poolParams.prefill = prefill; 267 } 268 269 public void setStrictMin(boolean strictMin) 270 { 271 poolParams.stictMin = strictMin; 272 273 } 274 275 public boolean getStrictMin() 276 { 277 278 return poolParams.stictMin; 279 280 } 281 282 public void flush() 283 { 284 if (poolingStrategy == null) 285 throw new IllegalStateException ("The connection pool is not started"); 286 287 poolingStrategy.flush(); 288 289 if (poolingStrategy instanceof PreFillPoolSupport) 290 { 291 final PreFillPoolSupport pfs = (PreFillPoolSupport) poolingStrategy; 292 293 if (pfs.shouldPreFill()) 294 pfs.prefill(noTxSeparatePools); 295 296 } 297 } 298 299 public int getConnectionCount() 300 { 301 return (poolingStrategy == null)? 0: poolingStrategy.getConnectionCount(); 302 } 303 304 public int getConnectionCreatedCount() 305 { 306 return (poolingStrategy == null)? 0: poolingStrategy.getConnectionCreatedCount(); 307 } 308 309 public int getConnectionDestroyedCount() 310 { 311 return (poolingStrategy == null)? 0: poolingStrategy.getConnectionDestroyedCount(); 312 } 313 314 public String getName() 315 { 316 return "JBossManagedConnectionPool"; 317 } 318 public String getStatisticsFormatter() 319 { 320 return statisticsFormatter; 321 } 322 323 public void setStatisticsFormatter(String statisticsFormatter) 324 { 325 this.statisticsFormatter = statisticsFormatter; 326 } 327 public String getPoolJndiName() 328 { 329 return this.poolJndiName; 330 } 331 332 public void setPoolJndiName(String poolName) 333 { 334 this.poolJndiName = poolName; 335 } 336 337 public boolean getBackGroundValidation() 338 { 339 return poolParams.backgroundValidation; 340 } 341 342 public void setBackGroundValidation(boolean backgroundValidation) 343 { 344 345 poolParams.backgroundValidation = backgroundValidation; 346 347 } 348 349 public long getBackGroundValidationMinutes() 350 { 351 352 return poolParams.backgroundInterval / (1000 * 60); 353 } 354 355 public void setBackGroundValidationMinutes(long backgroundValidationInterval) 356 { 357 358 poolParams.backgroundInterval = backgroundValidationInterval * 1000 * 60; 359 360 } 361 362 protected void startService() throws Exception 363 { 364 ManagedConnectionFactory mcf = null; 365 366 if (managedConnectionFactoryName == null) 367 throw new DeploymentException("ManagedConnectionFactory not set!"); 368 369 try 370 { 371 mcf = (ManagedConnectionFactory )server.getAttribute(managedConnectionFactoryName, "McfInstance"); 374 } 375 catch (Exception e) 376 { 377 JMXExceptionDecoder.rethrow(e); 378 } 379 380 getServer().addNotificationListener 381 ( 382 managedConnectionFactoryName, 383 this, 384 new NotificationFilter () 385 { 386 private static final long serialVersionUID = -9211456539783257343L; 387 388 public boolean isNotificationEnabled(Notification n) 389 { 390 return RARDeployment.MCF_ATTRIBUTE_CHANGED_NOTIFICATION.equals(n.getType()) 391 && managedConnectionFactoryName.equals(n.getSource()); 392 } 393 }, 394 null 395 ); 396 397 if ("ByContainerAndApplication".equals(criteria)) 398 poolingStrategy = new PoolBySubjectAndCri(mcf, poolParams, noTxSeparatePools, log); 399 else if ("ByContainer".equals(criteria)) 400 poolingStrategy = new PoolBySubject(mcf, poolParams, noTxSeparatePools, log); 401 else if ("ByApplication".equals(criteria)) 402 poolingStrategy = new PoolByCri(mcf, poolParams, noTxSeparatePools, log); 403 else if ("ByNothing".equals(criteria)) 404 poolingStrategy = new OnePool(mcf, poolParams, noTxSeparatePools, log); 405 else 406 throw new DeploymentException("Unknown pooling criteria: " + criteria); 407 } 408 409 protected void stopService() throws Exception 410 { 411 if (poolingStrategy != null) 412 poolingStrategy.shutdown(); 413 getServer().removeNotificationListener(managedConnectionFactoryName, this); 414 poolingStrategy = null; 415 } 416 417 public void handleNotification(Notification notification, 418 Object handback) 419 { 420 flush(); 421 } 422 423 public static class SubPoolContext 424 { 425 426 private InternalManagedConnectionPool subPool; 427 428 429 private TransactionLocal trackByTx; 430 431 442 public SubPoolContext(TransactionManager tm, ManagedConnectionFactory mcf, ConnectionListenerFactory clf, Subject subject, 443 ConnectionRequestInfo cri, PoolParams poolParams, Logger log) 444 { 445 subPool = new InternalManagedConnectionPool(mcf, clf, subject, cri, poolParams, log); 446 if (tm != null) 447 trackByTx = new TransactionLocal(tm); 448 } 449 450 455 public InternalManagedConnectionPool getSubPool() 456 { 457 return subPool; 458 } 459 460 465 public TransactionLocal getTrackByTx() 466 { 467 return trackByTx; 468 } 469 470 473 public void initialize() 474 { 475 subPool.initialize(); 476 } 477 } 478 479 482 public abstract static class BasePool implements ManagedConnectionPool, StatisticsReporter, PreFillPoolSupport 483 { 484 485 private final Map subPools = new ConcurrentReaderHashMap(); 486 487 488 private final ManagedConnectionFactory mcf; 489 490 491 private ConnectionListenerFactory clf; 492 493 494 private final InternalManagedConnectionPool.PoolParams poolParams; 495 496 497 private boolean noTxSeparatePools; 498 499 500 private String poolName; 501 502 private final Logger log; 503 504 505 private boolean traceEnabled = false; 506 507 514 public BasePool(final ManagedConnectionFactory mcf, final InternalManagedConnectionPool.PoolParams poolParams, 515 final boolean noTxSeparatePools, final Logger log) 516 { 517 this.mcf = mcf; 518 this.poolParams = poolParams; 519 this.noTxSeparatePools = noTxSeparatePools; 520 this.log = log; 521 this.traceEnabled = log.isTraceEnabled(); 522 } 523 524 532 protected abstract Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) throws ResourceException ; 533 534 535 public ManagedConnectionFactory getManagedConnectionFactory() 536 { 537 return mcf; 538 } 539 540 public void setConnectionListenerFactory(ConnectionListenerFactory clf) 541 { 542 this.clf = clf; 543 } 544 545 public ConnectionListener getConnection(Transaction trackByTransaction, Subject subject, ConnectionRequestInfo cri) 546 throws ResourceException 547 { 548 boolean separateNoTx = false; 550 if (noTxSeparatePools) 551 separateNoTx = clf.isTransactional(); 552 Object key = getKey(subject, cri, separateNoTx); 553 SubPoolContext subPool = getSubPool(key, subject, cri); 554 555 InternalManagedConnectionPool mcp = subPool.getSubPool(); 556 557 TransactionLocal trackByTx = subPool.getTrackByTx(); 559 560 if (trackByTransaction == null || trackByTx == null) 562 { 563 ConnectionListener cl = mcp.getConnection(subject, cri); 564 if (traceEnabled) 565 dump("Got connection from pool " + cl); 566 return cl; 567 } 568 569 try 571 { 572 trackByTx.lock(trackByTransaction); 573 } 574 catch (Throwable t) 575 { 576 JBossResourceException.rethrowAsResourceException("Unable to get connection from the pool for tx=" + trackByTransaction, t); 577 } 578 try 579 { 580 ConnectionListener cl = (ConnectionListener) trackByTx.get(trackByTransaction); 582 if (cl != null) 583 { 584 if (traceEnabled) 585 dump("Previous connection tracked by transaction " + cl + " tx=" + trackByTransaction); 586 return cl; 587 } 588 } 589 finally 590 { 591 trackByTx.unlock(trackByTransaction); 592 } 593 594 ConnectionListener cl = mcp.getConnection(subject, cri); 601 if (traceEnabled) 602 dump("Got connection from pool tracked by transaction " + cl + " tx=" + trackByTransaction); 603 604 try 606 { 607 trackByTx.lock(trackByTransaction); 608 } 609 catch (Throwable t) 610 { 611 mcp.returnConnection(cl, false); 612 if (traceEnabled) 613 dump("Had to return connection tracked by transaction " + cl + " tx=" + trackByTransaction + " error=" + t.getMessage()); 614 JBossResourceException.rethrowAsResourceException("Unable to get connection from the pool for tx=" + trackByTransaction, t); 615 } 616 try 617 { 618 ConnectionListener other = (ConnectionListener) trackByTx.get(trackByTransaction); 620 if (other != null) 621 { 622 mcp.returnConnection(cl, false); 623 if (traceEnabled) 624 dump("Another thread already got a connection tracked by transaction " + other + " tx=" + trackByTransaction); 625 return other; 626 } 627 628 cl.setTrackByTx(true); 630 trackByTx.set(cl); 631 if (traceEnabled) 632 dump("Using connection from pool tracked by transaction " + cl + " tx=" + trackByTransaction); 633 return cl; 634 } 635 finally 636 { 637 trackByTx.unlock(trackByTransaction); 638 } 639 } 640 641 public void returnConnection(ConnectionListener cl, boolean kill) throws ResourceException 642 { 643 cl.setTrackByTx(false); 644 InternalManagedConnectionPool mcp = (InternalManagedConnectionPool) cl.getContext(); 645 mcp.returnConnection(cl, kill); 646 if (traceEnabled) 647 dump("Returning connection to pool " + cl); 648 } 649 650 655 public int getInUseConnectionCount() 656 { 657 int count = 0; 658 synchronized (subPools) 659 { 660 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 661 { 662 SubPoolContext subPool = (SubPoolContext) i.next(); 663 count += subPool.getSubPool().getConnectionInUseCount(); 664 } 665 } 666 return count; 667 } 668 public boolean getPreFill() 669 { 670 return this.poolParams.prefill; 671 672 } 673 674 public boolean shouldPreFill() 675 { 676 return getPreFill(); 677 } 678 679 public void prefill() 680 { 681 682 prefill(null, null, false); 683 684 } 685 686 public void prefill(boolean noTxSeperatePool) 687 { 688 689 prefill(null, null, noTxSeperatePool); 690 691 } 692 693 public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxSeperatePool) 694 { 695 if (getPreFill()) 696 { 697 698 log.debug("Attempting to prefill pool for pool with jndi name" + poolName); 699 700 try 701 { 702 703 getSubPool(getKey(subject, cri, noTxSeparatePools), subject, cri); 704 705 } 706 catch (Throwable t) 707 { 708 log.error("Unable to prefill pool with jndi name" + getPoolName(), t); 710 711 } 712 713 } 714 715 } 716 717 public int getConnectionCount() 718 { 719 int count = 0; 720 synchronized (subPools) 721 { 722 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 723 { 724 SubPoolContext subPool = (SubPoolContext) i.next(); 725 count += subPool.getSubPool().getConnectionCount(); 726 } 727 } 728 return count; 729 } 730 731 public String getPoolName() 732 { 733 return poolName; 734 } 735 public int getConnectionCreatedCount() 736 { 737 int count = 0; 738 synchronized (subPools) 739 { 740 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 741 { 742 SubPoolContext subPool = (SubPoolContext) i.next(); 743 count += subPool.getSubPool().getConnectionCreatedCount(); 744 } 745 } 746 return count; 747 } 748 749 public int getConnectionDestroyedCount() 750 { 751 int count = 0; 752 synchronized (subPools) 753 { 754 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 755 { 756 SubPoolContext subPool = (SubPoolContext) i.next(); 757 count += subPool.getSubPool().getConnectionDestroyedCount(); 758 } 759 } 760 return count; 761 } 762 763 public long getAvailableConnectionCount() 764 { 765 long count = 0; 766 synchronized (subPools) 767 { 768 if (subPools.size() == 0) 769 return poolParams.maxSize; 770 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 771 { 772 SubPoolContext subPool = (SubPoolContext) i.next(); 773 count += subPool.getSubPool().getAvailableConnections(); 774 } 775 } 776 return count; 777 } 778 779 public int getMaxConnectionsInUseCount() 780 { 781 int count = 0; 782 synchronized (subPools) 783 { 784 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 785 { 786 SubPoolContext subPool = (SubPoolContext) i.next(); 787 count += subPool.getSubPool().getMaxConnectionsInUseCount(); 788 } 789 } 790 return count; 791 } 792 793 public void shutdown() 794 { 795 synchronized (subPools) 796 { 797 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 798 { 799 SubPoolContext subPool = (SubPoolContext) i.next(); 800 subPool.getSubPool().shutdown(); 801 } 802 subPools.clear(); 803 } 804 } 805 806 public void flush() 807 { 808 synchronized (subPools) 809 { 810 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 811 { 812 SubPoolContext subPool = (SubPoolContext) i.next(); 813 subPool.getSubPool().shutdown(); 814 } 815 subPools.clear(); 816 } 817 } 818 819 822 protected void shutdownWithoutClear() 823 { 824 synchronized (subPools) 825 { 826 for (Iterator i = subPools.values().iterator(); i.hasNext(); ) 827 { 828 SubPoolContext subPool = (SubPoolContext) i.next(); 829 subPool.getSubPool().shutdown(); 830 } 831 } 832 } 833 834 839 protected TransactionManager getTransactionManager() 840 { 841 if (clf != null) 842 return clf.getTransactionManagerInstance(); 843 else 844 return null; 845 } 846 847 857 protected SubPoolContext getSubPool(Object key, Subject subject, ConnectionRequestInfo cri) throws ResourceException 858 { 859 SubPoolContext subPool = (SubPoolContext) subPools.get(key); 860 if (subPool == null) 861 { 862 TransactionManager tm = getTransactionManager(); 863 subPool = new SubPoolContext(tm, mcf, clf, subject, cri, poolParams, log); 864 synchronized (subPools) 865 { 866 if (subPools.containsKey(key)) 867 subPool = (SubPoolContext) subPools.get(key); 868 else 869 { 870 subPool.initialize(); 871 subPools.put(key, subPool); 872 } 873 } 874 } 875 return subPool; 876 } 877 878 883 private void dump(String info) 884 { 885 if (traceEnabled) 886 { 887 StringBuffer toLog = new StringBuffer (100); 888 toLog.append(info).append(" [InUse/Available/Max]: ["); 889 toLog.append(this.getInUseConnectionCount()).append("/"); 890 toLog.append(this.getAvailableConnectionCount()).append("/"); 891 toLog.append(this.poolParams.maxSize); 892 toLog.append("]");; 893 log.trace(toLog); 894 } 895 } 896 897 public JBossStatistics listStatistics(){ 898 899 final ManagedConnectionPoolStatistics subPoolStats = new JBossManagedConnectionPoolStatistics(subPools.size()); 900 901 subPoolStats.setBlockingTimeout(poolParams.blockingTimeout); 902 subPoolStats.setIdleTimeout(poolParams.idleTimeout); 903 subPoolStats.setMax(poolParams.maxSize); 904 subPoolStats.setMin(poolParams.minSize); 905 subPoolStats.setPrefill(poolParams.prefill); 906 subPoolStats.setNoTxnSeperatePool(noTxSeparatePools); 907 908 909 910 for(Iterator iter = subPools.values().iterator(); iter.hasNext();){ 911 912 JBossSubPoolStatistics stat = new JBossSubPoolStatistics(); 913 SubPoolContext subContext = (SubPoolContext)iter.next(); 914 Boolean trackByTxn = (subContext.getTrackByTx() != null) ? Boolean.TRUE : Boolean.FALSE; 915 stat.setTrackByTxn(trackByTxn); 916 final InternalManagedConnectionPool internalPool = subContext.getSubPool(); 917 stat.setAvailableConnections(internalPool.getAvailableConnections()); 918 stat.setConnectionsDestroyed(internalPool.getConnectionDestroyedCount()); 919 stat.setConnectionsInUse(internalPool.getMaxConnectionsInUseCount()); 920 stat.setMaxConnectionsInUse(internalPool.getMaxConnectionsInUseCount()); 921 stat.setTotalBlockTime(internalPool.getTotalBlockTime()); 922 subPoolStats.addSubPool(stat); 923 924 925 } 926 927 return (JBossStatistics)subPoolStats; 928 } 929 } 930 931 934 public static class PoolBySubjectAndCri 935 extends BasePool 936 { 937 public PoolBySubjectAndCri(final ManagedConnectionFactory mcf, 938 final InternalManagedConnectionPool.PoolParams poolParams, 939 final boolean noTxSeparatePools, 940 final Logger log) 941 { 942 super(mcf, poolParams, noTxSeparatePools, log); 943 944 } 945 946 protected Object getKey(final Subject subject, final ConnectionRequestInfo cri, final boolean separateNoTx) throws ResourceException 947 { 948 return new SubjectCriKey(subject, cri, separateNoTx); 949 } 950 951 public void prefill() 952 { 953 prefill(null, null, false); 954 } 955 956 public void prefill(boolean noTxSeperatePool) 957 { 958 prefill(null, null, noTxSeperatePool); 959 } 960 961 public void prefill(Subject subject, ConnectionRequestInfo cri) 962 { 963 prefill(subject, cri, false); 964 965 } 966 967 public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxSeperatePool) 968 { 969 if (getPreFill()) 970 { 971 log.warn("Prefill pool option was selected for pool with JNDI name " + getPoolName() 972 + " that does not support this feature."); 973 log 974 .warn("Please verify your *-ds.xml file that corresponds with this resource and either remove the <prefill>true|false</prefill element or explicitly set this value to false."); 975 976 } 977 } 978 } 979 980 983 private static class SubjectCriKey 984 { 985 986 private static final Subject NOSUBJECT = new Subject (); 987 988 989 private static final Object NOCRI = new Object (); 990 991 992 private final Subject subject; 993 994 995 private final Object cri; 996 997 998 private int hashCode = Integer.MAX_VALUE; 999 1000 1001 private boolean separateNoTx; 1002 1003 SubjectCriKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) 1004 { 1005 this.subject = (subject == null)? NOSUBJECT:subject; 1006 this.cri = (cri == null)? NOCRI:cri; 1007 this.separateNoTx = separateNoTx; 1008 } 1009 1010 public int hashCode() 1011 { 1012 if (hashCode == Integer.MAX_VALUE) 1013 hashCode = SubjectActions.hashCode(subject) ^ cri.hashCode(); 1014 return hashCode; 1015 } 1016 1017 public boolean equals(Object obj) 1018 { 1019 if (this == obj) 1020 return true; 1021 if (obj == null || (obj instanceof SubjectCriKey) == false) 1022 return false; 1023 SubjectCriKey other = (SubjectCriKey) obj; 1024 return SubjectActions.equals(subject, other.subject) 1025 && cri.equals(other.cri) 1026 && separateNoTx == other.separateNoTx; 1027 } 1028 } 1029 1030 1033 public static class PoolBySubject 1034 extends BasePool 1035 { 1036 1037 public PoolBySubject(final ManagedConnectionFactory mcf, 1038 final InternalManagedConnectionPool.PoolParams poolParams, 1039 final boolean noTxSeparatePools, 1040 final Logger log) 1041 { 1042 super(mcf, poolParams, noTxSeparatePools, log); 1043 } 1044 1045 protected Object getKey(final Subject subject, final ConnectionRequestInfo cri, boolean separateNoTx) 1046 { 1047 return new SubjectKey(subject, separateNoTx); 1048 } 1049 1050 public void prefill() 1051 { 1052 prefill(null, null, false); 1053 } 1054 1055 public void prefill(boolean noTxSeperatePool) 1056 { 1057 prefill(null, null, noTxSeperatePool); 1058 } 1059 1060 public void prefill(Subject subject, ConnectionRequestInfo cri) 1061 { 1062 prefill(subject, cri, false); 1063 1064 } 1065 1066 public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxSeperatePool) 1067 { 1068 if (getPreFill()) 1069 { 1070 log.warn("Prefill pool option was selected for pool with JNDI name " + getPoolName() 1071 + " that does not support this feature."); 1072 log 1073 .warn("Please verify your *-ds.xml file that corresponds with this resource and either remove the <prefill>true|false</prefill element or explicitly set this value to false."); 1074 1075 } 1076 } 1077 } 1078 1079 1082 private static class SubjectKey 1083 { 1084 1085 private static final Subject NOSUBJECT = new Subject (); 1086 1087 1088 private final Subject subject; 1089 1090 1091 private boolean separateNoTx; 1092 1093 1094 private int hashCode = Integer.MAX_VALUE; 1095 1096 SubjectKey(Subject subject, boolean separateNoTx) 1097 { 1098 this.subject = (subject == null)? NOSUBJECT:subject; 1099 this.separateNoTx = separateNoTx; 1100 } 1101 1102 public int hashCode() 1103 { 1104 if (hashCode == Integer.MAX_VALUE) 1105 hashCode = SubjectActions.hashCode(subject); 1106 return hashCode; 1107 } 1108 1109 public boolean equals(Object obj) 1110 { 1111 if (this == obj) 1112 return true; 1113 if (obj == null || (obj instanceof SubjectKey) == false) 1114 return false; 1115 SubjectKey other = (SubjectKey) obj; 1116 return SubjectActions.equals(subject, other.subject) 1117 && separateNoTx == other.separateNoTx; 1118 } 1119 } 1120 1121 1124 public static class PoolByCri 1125 extends BasePool 1126 { 1127 public PoolByCri(final ManagedConnectionFactory mcf, 1128 final InternalManagedConnectionPool.PoolParams poolParams, 1129 final boolean noTxSeparatePools, 1130 final Logger log) 1131 { 1132 super(mcf, poolParams, noTxSeparatePools, log); 1133 } 1134 1135 protected Object getKey(final Subject subject, final ConnectionRequestInfo cri, boolean separateNoTx) 1136 { 1137 return new CriKey(cri, separateNoTx); 1138 } 1139 1140 public void prefill() 1141 { 1142 prefill(null, null, false); 1143 } 1144 1145 public void prefill(boolean noTxSeperatePool) 1146 { 1147 prefill(null, null, noTxSeperatePool); 1148 } 1149 1150 public void prefill(Subject subject, ConnectionRequestInfo cri) 1151 { 1152 prefill(subject, cri, false); 1153 1154 } 1155 1156 public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxSeperatePool) 1157 { 1158 if (getPreFill()) 1159 { 1160 log.warn("Prefill pool option was selected for pool with JNDI name " + getPoolName() 1161 + " that does not support this feature."); 1162 log 1163 .warn("Please verify your *-ds.xml file that corresponds with this resource and either remove the <prefill>true|false</prefill element or explicitly set this value to false."); 1164 1165 } 1166 } 1167 } 1168 1169 1172 private static class CriKey 1173 { 1174 1175 private static final Object NOCRI = new Object (); 1176 1177 1178 private final Object cri; 1179 1180 1181 private boolean separateNoTx; 1182 1183 1184 private int hashCode = Integer.MAX_VALUE; 1185 1186 CriKey(ConnectionRequestInfo cri, boolean separateNoTx) 1187 { 1188 this.cri = (cri == null)? NOCRI : cri; 1189 this.separateNoTx = separateNoTx; 1190 } 1191 1192 public int hashCode() 1193 { 1194 if (hashCode == Integer.MAX_VALUE) 1195 hashCode = cri.hashCode(); 1196 return hashCode; 1197 } 1198 1199 public boolean equals(Object obj) 1200 { 1201 if (this == obj) 1202 return true; 1203 if (obj == null || (obj instanceof CriKey) == false) 1204 return false; 1205 CriKey other = (CriKey) obj; 1206 return cri.equals(other.cri) && separateNoTx == other.separateNoTx; 1207 } 1208 } 1209 1210 1213 public static class OnePool 1214 extends BasePool 1215 { 1216 public OnePool(final ManagedConnectionFactory mcf, 1217 final InternalManagedConnectionPool.PoolParams poolParams, 1218 final boolean noTxSeparatePools, 1219 final Logger log) 1220 { 1221 super(mcf, poolParams, noTxSeparatePools, log); 1222 } 1223 1224 protected Object getKey(final Subject subject, final ConnectionRequestInfo cri, boolean separateNoTx) 1225 { 1226 if (separateNoTx) 1227 return Boolean.TRUE; 1228 else 1229 return Boolean.FALSE; 1230 } 1231 1232 public void prefill(Subject sub){ 1233 1234 log.debug("Attempting to prefill pool" + getClass()); 1235 1236 try 1237 { 1238 getSubPool(getKey(null, null, false), null, null); 1240 1241 } 1242 1243 catch (ResourceException e) 1244 { 1245 log.error("Prefill failed for pool instance " + getClass(), e); 1246 1247 } 1248 1249 } 1250 } 1251 1252 private static class SubjectActions implements PrivilegedAction 1253 { 1254 Subject subject; 1255 Subject other; 1256 SubjectActions(Subject subject, Subject other) 1257 { 1258 this.subject = subject; 1259 this.other = other; 1260 } 1261 public Object run() 1262 { 1263 Object value = null; 1264 if( other == null ) 1265 value = new Integer (subject.hashCode()); 1266 else 1267 value = new Boolean (subject.equals(other)); 1268 return value; 1269 } 1270 static int hashCode(Subject subject) 1271 { 1272 SubjectActions action = new SubjectActions(subject, null); 1273 Integer hash = (Integer ) AccessController.doPrivileged(action); 1274 return hash.intValue(); 1275 } 1276 static boolean equals(Subject subject, Subject other) 1277 { 1278 SubjectActions action = new SubjectActions(subject, other); 1279 Boolean equals = (Boolean ) AccessController.doPrivileged(action); 1280 return equals.booleanValue(); 1281 } 1282 } 1283 1284 1285 1286 1287} 1288 | Popular Tags |