Author: shawkins
Date: 2012-06-28 15:54:38 -0400 (Thu, 28 Jun 2012)
New Revision: 4210
Modified:
branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html
branches/7.7.x/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java
branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java
branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
branches/7.7.x/documentation/admin-guide/src/main/docbook/en-US/content/appendix-c.xml
branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
branches/7.7.x/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
branches/7.7.x/runtime/src/main/java/org/teiid/deployers/VDBRepository.java
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistry.java
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistryImpl.java
branches/7.7.x/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
branches/7.7.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
Log:
TEIID-2059 adding logic for local connection to wait until vdbs are active
Modified: branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html 2012-06-27 19:35:38
UTC (rev 4209)
+++ branches/7.7.x/build/kits/jboss-container/teiid-releasenotes.html 2012-06-28 19:54:38
UTC (rev 4210)
@@ -43,6 +43,7 @@
<li>Support for named parameter syntax using param=value has been deprecated,
since it is ambiguous with a comparison predicate boolean value expression.
param<b>=></b>value should be used instead.
<li>Support for using the FROM clause post item hints MAKEDEP/MAKENOTDEP has been
deprecated. Use the pre item comment hint syntax instead, e.g. /*+ MAKEDEP */ tbl
<li>decodeinteger/decodestring have been deprecated. A CASE expression should be
used instead.
+ <li>local connections specifying a VDB version will wait for their VDB to finish
loading before allowing a connection. See the connection property waitForLoad or the
system property org.teiid.clientVdbLoadTimeoutMillis for more.
</ul>
<h4>from 7.7</h4>
Modified: branches/7.7.x/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java 2012-06-27
19:35:38 UTC (rev 4209)
+++ branches/7.7.x/client/src/main/java/org/teiid/jdbc/EmbeddedProfile.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -38,6 +38,7 @@
public class EmbeddedProfile implements ConnectionProfile {
public static final String USE_CALLING_THREAD = "useCallingThread";
//$NON-NLS-1$
+ public static final String WAIT_FOR_LOAD = "waitForLoad"; //$NON-NLS-1$
/**
* This method tries to make a connection to the given URL. This class
Modified: branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java
===================================================================
--- branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2012-06-27 19:35:38
UTC (rev 4209)
+++ branches/7.7.x/client/src/main/java/org/teiid/jdbc/JDBCURL.java 2012-06-28 19:54:38
UTC (rev 4210)
@@ -71,6 +71,7 @@
BaseDataSource.VDB_VERSION,
BaseDataSource.USER_NAME,
BaseDataSource.PASSWORD,
+ EmbeddedProfile.WAIT_FOR_LOAD,
TeiidURL.CONNECTION.AUTO_FAILOVER,
TeiidURL.CONNECTION.DISCOVERY_STRATEGY,
TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION,
Modified: branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java
===================================================================
--- branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2012-06-27
19:35:38 UTC (rev 4209)
+++ branches/7.7.x/client/src/test/java/org/teiid/jdbc/TestTeiidDriver.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -138,7 +138,7 @@
@Test public void testGetPropertyInfo1() throws Exception {
DriverPropertyInfo info[] =
drv.getPropertyInfo("jdbc:teiid:vdb@mm://localhost:12345;applicationName=x",
null); //$NON-NLS-1$
- assertEquals(24, info.length);
+ assertEquals(25, info.length);
assertEquals(false, info[0].required);
assertEquals("ApplicationName", info[0].name); //$NON-NLS-1$
assertEquals("x", info[0].value); //$NON-NLS-1$
Modified:
branches/7.7.x/documentation/admin-guide/src/main/docbook/en-US/content/appendix-c.xml
===================================================================
---
branches/7.7.x/documentation/admin-guide/src/main/docbook/en-US/content/appendix-c.xml 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/documentation/admin-guide/src/main/docbook/en-US/content/appendix-c.xml 2012-06-28
19:54:38 UTC (rev 4210)
@@ -51,5 +51,10 @@
</para>
<note><para>For Teiid 8.x this property no longer exists and the default
behavior is to add only the Warning root.</para></note>
</listitem>
+ <listitem>
+ <para><emphasis>org.teiid.clientVdbLoadTimeoutMillis</emphasis> -
defaults to 5 minutes.
+ The default amount of time a client (currently only local clients) will wait to make a
connection to an active VDB before throwing an exception. Clients may override this
setting via the waitForLoad connection property.
+ </para>
+ </listitem>
</itemizedlist>
</appendix>
\ No newline at end of file
Modified:
branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml
===================================================================
---
branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/documentation/client-developers-guide/src/main/docbook/en-US/content/jdbc-connection.xml 2012-06-28
19:54:38 UTC (rev 4210)
@@ -232,6 +232,15 @@
<code>boolean</code>
</entry>
<entry>Only applies to "local" connections. When
this option is set to "true" (the default), then the calling thread will be used
to process the query. If false, then an engine thread will be used.</entry>
+ </row>
+ <row>
+ <entry>
+ <code>waitForLoad</code>
+ </entry>
+ <entry>
+ <code>integer</code>
+ </entry>
+ <entry>Only applies to "local" connections. When
this option is set to a non-negative value the connection will wait that number of
milliseconds for the VDB to become active. Setting to a negative number will use the
system default setting. Needs to be specified using AdditionalProperties if set via a
DataSource property.</entry>
</row>
<row>
<entry>
Modified:
branches/7.7.x/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
===================================================================
---
branches/7.7.x/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -113,6 +113,7 @@
import org.teiid.metadata.Table;
import org.teiid.metadata.TableStats;
import org.teiid.metadata.Table.TriggerEvent;
+import org.teiid.net.ConnectionException;
import org.teiid.net.TeiidURL;
import org.teiid.net.socket.AuthenticationType;
import org.teiid.query.ObjectReplicator;
@@ -883,4 +884,14 @@
public AuthenticationType getAuthenticationType() {
return this.sessionService.getAuthType();
}
+
+ @Override
+ public void waitForFinished(String vdbName, int vdbVersion,
+ int timeOutMillis) throws ConnectionException {
+ try {
+ vdbRepository.waitForFinished(vdbName, vdbVersion, timeOutMillis);
+ } catch (InterruptedException e) {
+ return; //just allow the thread to continue/error
+ }
+ }
}
Modified: branches/7.7.x/runtime/src/main/java/org/teiid/deployers/VDBRepository.java
===================================================================
--- branches/7.7.x/runtime/src/main/java/org/teiid/deployers/VDBRepository.java 2012-06-27
19:35:38 UTC (rev 4209)
+++ branches/7.7.x/runtime/src/main/java/org/teiid/deployers/VDBRepository.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -22,39 +22,26 @@
package org.teiid.deployers;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.Properties;
+import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
import org.jboss.deployers.spi.DeploymentException;
import org.teiid.adminapi.AdminException;
import org.teiid.adminapi.AdminProcessingException;
+import org.teiid.adminapi.VDB.Status;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.core.CoreConstants;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.util.PropertiesUtils;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
-import org.teiid.metadata.AbstractMetadataRecord;
-import org.teiid.metadata.Column;
-import org.teiid.metadata.ColumnStats;
-import org.teiid.metadata.Datatype;
-import org.teiid.metadata.MetadataRepository;
-import org.teiid.metadata.MetadataStore;
-import org.teiid.metadata.Procedure;
-import org.teiid.metadata.Schema;
-import org.teiid.metadata.Table;
-import org.teiid.metadata.TableStats;
+import org.teiid.metadata.*;
+import org.teiid.net.ConnectionException;
import org.teiid.query.function.SystemFunctionManager;
import org.teiid.query.metadata.TransformationMetadata.Resource;
import org.teiid.runtime.RuntimePlugin;
@@ -67,6 +54,7 @@
*/
public class VDBRepository implements Serializable{
private static final long serialVersionUID = 312177538191772674L;
+ private static final int DEFAULT_TIMEOUT_MILLIS =
PropertiesUtils.getIntProperty(System.getProperties(),
"org.teiid.clientVdbLoadTimeoutMillis", 300000); //$NON-NLS-1$
private NavigableMap<VDBKey, CompositeVDB> vdbRepo = new
ConcurrentSkipListMap<VDBKey, CompositeVDB>();
private MetadataStore systemStore;
@@ -75,15 +63,15 @@
private List<VDBLifeCycleListener> listeners = new
CopyOnWriteArrayList<VDBLifeCycleListener>();
private SystemFunctionManager systemFunctionManager;
private MetadataRepository metadataRepository;
+ private ReentrantLock lock = new ReentrantLock();
+ private Condition vdbAdded = lock.newCondition();
public MetadataRepository getMetadataRepository() {
return metadataRepository;
}
public void addVDB(VDBMetaData vdb, MetadataStoreGroup stores, LinkedHashMap<String,
Resource> visibilityMap, UDFMetaData udf, ConnectorManagerRepository cmr) throws
DeploymentException {
- if (getVDB(vdb.getName(), vdb.getVersion()) != null) {
- throw new DeploymentException(RuntimePlugin.Util.getString("duplicate_vdb",
vdb.getName(), vdb.getVersion())); //$NON-NLS-1$
- }
+ VDBKey key = vdbId(vdb);
// get the system VDB metadata store
if (this.systemStore == null) {
@@ -100,6 +88,16 @@
else {
cvdb = new CompositeVDB(vdb, stores, visibilityMap, udf,
this.systemFunctionManager.getSystemFunctions(), cmr, this.systemStore, odbcStore);
}
+ lock.lock();
+ try {
+ if (vdbRepo.containsKey(key)) {
+ throw new DeploymentException(RuntimePlugin.Util.getString("duplicate_vdb",
vdb.getName(), vdb.getVersion())); //$NON-NLS-1$
+ }
+ this.vdbRepo.put(key, cvdb);
+ vdbAdded.signalAll();
+ } finally {
+ lock.unlock();
+ }
this.vdbRepo.put(vdbId(vdb), cvdb);
notifyAdd(vdb.getName(), vdb.getVersion(), cvdb);
}
@@ -188,6 +186,40 @@
}
metadataRepository.endLoadVdb(vdbName, vdbVersion);
}
+
+ public void waitForFinished(String vdbName, int vdbVersion, int timeOutMillis) throws
InterruptedException, ConnectionException {
+ CompositeVDB cvdb = null;
+ VDBKey key = new VDBKey(vdbName, vdbVersion);
+ long timeOutNanos = 0;
+ if (timeOutMillis >= 0) {
+ timeOutNanos = TimeUnit.MILLISECONDS.toNanos(DEFAULT_TIMEOUT_MILLIS);
+ } else {
+ //TODO allow a configurable default
+ timeOutNanos = TimeUnit.MINUTES.toNanos(10);
+ }
+ lock.lock();
+ try {
+ while ((cvdb = this.vdbRepo.get(key)) == null) {
+ if (timeOutNanos <= 0) {
+ throw new
ConnectionException(RuntimePlugin.Util.getString("VDBRepository.no_vdb",
timeOutMillis, vdbName, vdbVersion)); //$NON-NLS-1$
+ }
+ timeOutNanos = this.vdbAdded.awaitNanos(timeOutNanos);
+ }
+ } finally {
+ lock.unlock();
+ }
+ VDBMetaData vdb = cvdb.getVDB();
+ long finishNanos = System.nanoTime() + timeOutNanos;
+ synchronized (vdb) {
+ while (vdb.getStatus() != Status.ACTIVE) {
+ if (timeOutNanos <= 0) {
+ throw new
ConnectionException(RuntimePlugin.Util.getString("VDBRepository.no_vdb",
timeOutMillis, vdbName, vdbVersion, vdb.getValidityErrors())); //$NON-NLS-1$
+ }
+ vdb.wait(timeOutNanos);
+ timeOutNanos = finishNanos - System.nanoTime();
+ }
+ }
+ }
public VDBMetaData getVDB(String name, int version) {
CompositeVDB v = this.vdbRepo.get(new VDBKey(name, version));
Modified:
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistry.java
===================================================================
---
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistry.java 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistry.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -23,6 +23,7 @@
package org.teiid.transport;
import org.teiid.core.ComponentNotFoundException;
+import org.teiid.net.ConnectionException;
import org.teiid.net.socket.AuthenticationType;
import org.teiid.security.SecurityHelper;
@@ -38,5 +39,7 @@
SecurityHelper getSecurityHelper();
AuthenticationType getAuthenticationType();
+
+ void waitForFinished(String vdbName, int vdbVersion, int timeOutMillis) throws
ConnectionException;
}
Modified:
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistryImpl.java
===================================================================
---
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistryImpl.java 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/runtime/src/main/java/org/teiid/transport/ClientServiceRegistryImpl.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -26,6 +26,7 @@
import org.teiid.core.ComponentNotFoundException;
import org.teiid.core.util.ReflectionHelper;
+import org.teiid.net.ConnectionException;
import org.teiid.net.socket.AuthenticationType;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.security.SecurityHelper;
@@ -103,5 +104,11 @@
public AuthenticationType getAuthenticationType() {
return authenticationType;
}
+
+ @Override
+ public void waitForFinished(String vdbName, int vdbVersion,
+ int timeOutMillis) throws ConnectionException {
+ }
+
}
Modified:
branches/7.7.x/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java
===================================================================
---
branches/7.7.x/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/runtime/src/main/java/org/teiid/transport/LocalServerConnection.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -40,7 +40,9 @@
import org.teiid.client.util.ExceptionUtil;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidRuntimeException;
+import org.teiid.core.util.PropertiesUtils;
import org.teiid.dqp.internal.process.DQPWorkContext;
+import org.teiid.jdbc.EmbeddedProfile;
import org.teiid.net.CommunicationException;
import org.teiid.net.ConnectionException;
import org.teiid.net.ServerConnection;
@@ -61,6 +63,22 @@
public LocalServerConnection(Properties connectionProperties, boolean useCallingThread)
throws CommunicationException, ConnectionException{
this.connectionProperties = connectionProperties;
this.csr = getClientServiceRegistry();
+
+ String vdbVersion = connectionProperties.getProperty(TeiidURL.JDBC.VDB_VERSION);
+ String vdbName = connectionProperties.getProperty(TeiidURL.JDBC.VDB_NAME);
+ int firstIndex = vdbName.indexOf('.');
+ int lastIndex = vdbName.lastIndexOf('.');
+ if (firstIndex != -1 && firstIndex == lastIndex) {
+ vdbVersion = vdbName.substring(firstIndex+1);
+ vdbName = vdbName.substring(0, firstIndex);
+ }
+ if (vdbVersion != null) {
+ int waitForLoad = PropertiesUtils.getIntProperty(connectionProperties,
EmbeddedProfile.WAIT_FOR_LOAD, -1);
+ if (waitForLoad != 0) {
+ this.csr.waitForFinished(vdbName, Integer.valueOf(vdbVersion), waitForLoad);
+ }
+ }
+
workContext.setSecurityHelper(csr.getSecurityHelper());
workContext.setUseCallingThread(useCallingThread);
authenticate();
Modified: branches/7.7.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- branches/7.7.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2012-06-27
19:35:38 UTC (rev 4209)
+++ branches/7.7.x/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2012-06-28
19:54:38 UTC (rev 4210)
@@ -101,4 +101,7 @@
wrong_logon_type_krb5 = Wrong logon method is being used. Server is not set up for
Kerberos based authentication. Correct your client's 'AuthenticationType'
property.
krb5_login_failed=Kerberos context login failed
no_security_domains=No security domain configured for Kerberos authentication. Can not
authenticate.
-krb5_user_not_found=GSS authentication is in use, however authenticated user not found in
the context to proceed.
\ No newline at end of file
+krb5_user_not_found=GSS authentication is in use, however authenticated user not found in
the context to proceed.
+
+VDBRepository.no_vdb=Waited {0} for VDB {1}.{2} to be deployed, but it never was. Please
check to see if the deployment is missing or is in error.
+VDBRepository.vdb_not_active=Waited {0} for VDB {1}.{2} to be ACTIVE, but it never was.
Please check it's sources - {3}.
\ No newline at end of file
Modified:
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java
===================================================================
---
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/FakeServer.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -299,4 +299,14 @@
return new ConnectionImpl(conn, info, url);
}
+ @Override
+ public void waitForFinished(String vdbName, int vdbVersion,
+ int timeOutMillis) throws ConnectionException {
+ try {
+ repo.waitForFinished(vdbName, vdbVersion, timeOutMillis);
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+
}
Modified:
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java
===================================================================
---
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2012-06-27
19:35:38 UTC (rev 4209)
+++
branches/7.7.x/test-integration/common/src/test/java/org/teiid/jdbc/TestLocalConnections.java 2012-06-28
19:54:38 UTC (rev 4210)
@@ -43,6 +43,7 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.teiid.client.util.ResultsFuture;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.util.UnitTestUtil;
import org.teiid.dqp.internal.datamgr.ConnectorManager;
@@ -334,4 +335,28 @@
}
}
+ @Test public void testWaitForLoad() throws Exception {
+ final ResultsFuture<Void> future = new ResultsFuture<Void>();
+
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ server.createConnection("jdbc:teiid:not_there.1");
+ future.getResultsReceiver().receiveResults(null);
+ } catch (Exception e) {
+ future.getResultsReceiver().exceptionOccurred(e);
+ }
+ }
+ };
+ t.setDaemon(true);
+ t.start();
+ assertFalse(future.isDone());
+ try {
+ server.deployVDB("not_there", UnitTestUtil.getTestDataPath() +
"/PartsSupplier.vdb");
+ future.get(5000, TimeUnit.SECONDS);
+ } finally {
+ server.undeployVDB("not_there");
+ }
+ }
+
}