[teiid-commits] teiid SVN: r2372 - in trunk: engine/src/main/java/org/teiid/dqp/internal and 7 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Fri Jul 23 23:25:42 EDT 2010


Author: shawkins
Date: 2010-07-23 23:25:41 -0400 (Fri, 23 Jul 2010)
New Revision: 2372

Added:
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/TransactionServerImpl.java
   trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java
   trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestTransactionServer.java
Removed:
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/validator/
   trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/
   trunk/engine/src/test/java/org/teiid/dqp/internal/process/validator/
   trunk/engine/src/test/java/org/teiid/dqp/internal/transaction/
Modified:
   trunk/engine/src/main/java/org/teiid/common/buffer/STree.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
   trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
   trunk/engine/src/test/java/org/teiid/common/queue/TestThreadReuseExecutor.java
   trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeTransactionService.java
   trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
Log:
TEIID-1167 removing unnecessary buffering and minor repackaging

Modified: trunk/engine/src/main/java/org/teiid/common/buffer/STree.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/STree.java	2010-07-23 21:44:19 UTC (rev 2371)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/STree.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -334,6 +334,24 @@
 				}
 			}
 		}
+		
+		/**
+		 * Perform an in-place update of the tuple just returned by the next method
+		 * WARNING - this must not change the key value
+		 * @param tuple
+		 * @throws TeiidComponentException
+		 */
+		public void update(List tuple) throws TeiidComponentException {
+			values.set(index - 1, tuple);
+			page.setValues(values);
+		}
+		
+		/**
+		 * Notify the browser that the last value was deleted.
+		 */
+		public void removed() {
+			index--;
+		}
 	}
 	
 	public int getKeyLength() {

Copied: trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java (from rev 2371, trunk/engine/src/main/java/org/teiid/dqp/internal/process/validator/AuthorizationValidationVisitor.java)
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/AuthorizationValidationVisitor.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -0,0 +1,357 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.dqp.internal.process;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.teiid.adminapi.DataPolicy;
+import org.teiid.adminapi.impl.DataPolicyMetadata;
+import org.teiid.adminapi.impl.ModelMetaData;
+import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.dqp.DQPPlugin;
+import org.teiid.dqp.internal.process.multisource.MultiSourceElement;
+import org.teiid.logging.AuditMessage;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.logging.MessageLevel;
+import org.teiid.query.function.FunctionLibrary;
+import org.teiid.query.metadata.TempMetadataID;
+import org.teiid.query.resolver.util.ResolverUtil;
+import org.teiid.query.sql.lang.Delete;
+import org.teiid.query.sql.lang.Insert;
+import org.teiid.query.sql.lang.Into;
+import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.StoredProcedure;
+import org.teiid.query.sql.lang.Update;
+import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.Function;
+import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.Symbol;
+import org.teiid.query.sql.visitor.ElementCollectorVisitor;
+import org.teiid.query.sql.visitor.GroupCollectorVisitor;
+import org.teiid.query.validator.AbstractValidationVisitor;
+
+
+public class AuthorizationValidationVisitor extends AbstractValidationVisitor {
+    
+	public enum Context {
+		QUERY,
+		INSERT,
+		UPDATE,
+		DELETE,
+		STORED_PROCEDURE;
+    }
+    
+    private VDBMetaData vdb;
+    private HashMap<String, DataPolicy> allowedPolicies;
+    private String userName;
+    private boolean useEntitlements;
+
+    public AuthorizationValidationVisitor(VDBMetaData vdb, boolean useEntitlements, HashMap<String, DataPolicy> policies, String user) {
+        this.vdb = vdb;
+        this.allowedPolicies = policies;
+        this.userName = user;
+        this.useEntitlements = useEntitlements;
+    }
+
+    // ############### Visitor methods for language objects ##################
+    
+    @Override
+    public void visit(GroupSymbol obj) {
+    	try {
+    		Object modelID = getMetadata().getModelID(obj.getMetadataID());
+    		this.validateModelVisibility(modelID, obj);
+	    } catch(QueryMetadataException e) {
+	        handleException(e, obj);
+	    } catch(TeiidComponentException e) {
+	        handleException(e, obj);
+	    }
+    }
+
+    public void visit(Delete obj) {
+    	validateEntitlements(obj);
+    }
+
+    public void visit(Insert obj) {
+    	validateEntitlements(obj);
+    }
+
+    public void visit(Query obj) {
+    	validateEntitlements(obj);
+    }
+
+    public void visit(Update obj) {
+    	validateEntitlements(obj);
+    }
+
+    public void visit(StoredProcedure obj) {
+    	this.validateModelVisibility(obj.getModelID(), obj.getGroup());
+    	validateEntitlements(obj);
+    }
+    
+    public void visit(Function obj) {
+    	if (FunctionLibrary.LOOKUP.equalsIgnoreCase(obj.getName())) {
+    		try {
+				ResolverUtil.ResolvedLookup lookup = ResolverUtil.resolveLookup(obj, this.getMetadata());
+	    		validateModelVisibility(getMetadata().getModelID(lookup.getGroup().getMetadataID()), lookup.getGroup());
+    			List<Symbol> symbols = new LinkedList<Symbol>();
+				symbols.add(lookup.getGroup());
+				symbols.add(lookup.getKeyElement());
+				symbols.add(lookup.getReturnElement());
+	    		validateEntitlements(symbols, DataPolicy.PermissionType.READ, Context.QUERY);
+			} catch (TeiidComponentException e) {
+				handleException(e, obj);
+			} catch (TeiidProcessingException e) {
+				handleException(e, obj);
+			}
+    	}
+    }
+
+    // ######################### Validation methods #########################
+
+    /**
+     * Validate insert entitlements
+     */
+    protected void validateEntitlements(Insert obj) {
+        validateEntitlements(
+            obj.getVariables(),
+            DataPolicy.PermissionType.CREATE,
+            Context.INSERT);
+    }
+
+    /**
+     * Validate update entitlements
+     */
+    protected void validateEntitlements(Update obj) {
+        // Check that all elements used in criteria have read permission
+        if (obj.getCriteria() != null) {
+            validateEntitlements(
+                ElementCollectorVisitor.getElements(obj.getCriteria(), true),
+                DataPolicy.PermissionType.READ,
+                Context.UPDATE);
+        }
+
+        // The variables from the changes must be checked for UPDATE entitlement
+        // validateEntitlements on all the variables used in the update.
+        validateEntitlements(obj.getChangeList().getClauseMap().keySet(), DataPolicy.PermissionType.UPDATE, Context.UPDATE);
+    }
+
+    /**
+     * Validate delete entitlements
+     */
+    protected void validateEntitlements(Delete obj) {
+        // Check that all elements used in criteria have read permission
+        if (obj.getCriteria() != null) {
+            validateEntitlements(
+                ElementCollectorVisitor.getElements(obj.getCriteria(), true),
+                DataPolicy.PermissionType.READ,
+                Context.DELETE);
+        }
+
+        // Check that all elements of group being deleted have delete permission
+        HashSet deleteVars = new HashSet();
+        deleteVars.add(obj.getGroup());
+        validateEntitlements(deleteVars, DataPolicy.PermissionType.DELETE, Context.DELETE);
+    }
+
+    /**
+     * Validate query entitlements
+     */
+    protected void validateEntitlements(Query obj) {
+        // If query contains SELECT INTO, validate INTO portion
+        Into intoObj = obj.getInto();
+        if ( intoObj != null ) {
+            GroupSymbol intoGroup = intoObj.getGroup();
+            List intoElements = null;
+            try {
+                intoElements = ResolverUtil.resolveElementsInGroup(intoGroup, getMetadata());
+            } catch (QueryMetadataException err) {
+                handleException(err, intoGroup);
+            } catch (TeiidComponentException err) {
+                handleException(err, intoGroup);
+            }
+            validateEntitlements(intoElements,
+                                 DataPolicy.PermissionType.CREATE,
+                                 Context.INSERT);
+        }
+
+        // Validate this query's entitlements
+        Collection entitledObjects = GroupCollectorVisitor.getGroups(obj, true);
+        if (!isXMLCommand(obj)) {
+            entitledObjects.addAll(ElementCollectorVisitor.getElements(obj, true));
+        }
+
+        if(entitledObjects.size() == 0) {
+            return;
+        }
+        
+        validateEntitlements(entitledObjects, DataPolicy.PermissionType.READ, Context.QUERY);
+    }
+
+    /**
+     * Validate query entitlements
+     */
+    protected void validateEntitlements(StoredProcedure obj) {
+        List symbols = new ArrayList(1);
+        symbols.add(obj.getGroup());
+        validateEntitlements(symbols, DataPolicy.PermissionType.READ, Context.STORED_PROCEDURE);
+    }
+
+    private String getActionLabel(DataPolicy.PermissionType actionCode) {
+        switch(actionCode) {
+            case READ:    return "Read"; //$NON-NLS-1$
+            case CREATE:  return "Create"; //$NON-NLS-1$
+            case UPDATE:  return "Update"; //$NON-NLS-1$
+            case DELETE:  return "Delete"; //$NON-NLS-1$
+            default:    return "UNKNOWN"; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Check that the user is entitled to access all data elements in the command.
+     *
+     * @param symbols The collection of <code>Symbol</code>s affected by these actions.
+     * @param actionCode The actions to validate for
+     * @param auditContext The {@link AuthorizationService} to use when resource auditing is done.
+     */
+    protected void validateEntitlements(Collection symbols, DataPolicy.PermissionType actionCode, Context auditContext) {
+        Map nameToSymbolMap = new HashMap();
+        Iterator symbolIter = symbols.iterator();
+        while(symbolIter.hasNext()) {
+            Object symbol = symbolIter.next();
+            try {
+                String fullName = null;
+                Object metadataID = null;
+                if(symbol instanceof ElementSymbol) {                    
+                    metadataID = ((ElementSymbol)symbol).getMetadataID();
+                    if (metadataID instanceof MultiSourceElement || metadataID instanceof TempMetadataID) {
+                        continue;
+                    }
+                } else if(symbol instanceof GroupSymbol) {
+                    GroupSymbol group = (GroupSymbol)symbol;
+                    metadataID = group.getMetadataID();
+                    if (metadataID instanceof TempMetadataID && !group.isProcedure()) {
+                        continue;
+                    }
+                }
+                fullName = getMetadata().getFullName(metadataID);
+                nameToSymbolMap.put(fullName, symbol);
+            } catch(QueryMetadataException e) {
+                handleException(e);
+            } catch(TeiidComponentException e) {
+                handleException(e);
+            }
+        }
+
+        if (!nameToSymbolMap.isEmpty()) {
+            Collection inaccessibleResources = getInaccessibleResources(actionCode, nameToSymbolMap.keySet(), auditContext);
+            if(inaccessibleResources.size() > 0) {                              
+                List inaccessibleSymbols = new ArrayList(inaccessibleResources.size());
+                Iterator nameIter = inaccessibleResources.iterator();
+                while(nameIter.hasNext()) {
+                    String name = (String) nameIter.next();
+                    inaccessibleSymbols.add(nameToSymbolMap.get(name));
+                }
+                
+                // CASE 2362 - do not include the names of the elements for which the user
+                // is not authorized in the exception message
+                
+                handleValidationError(
+                    DQPPlugin.Util.getString("ERR.018.005.0095", new Object[]{DQPWorkContext.getWorkContext().getSessionId(), getActionLabel(actionCode)}), //$NON-NLS-1$                    
+                    inaccessibleSymbols);
+            }
+        }
+
+    }
+
+    protected void validateModelVisibility(Object modelID, GroupSymbol group) {
+        if(modelID instanceof TempMetadataID){
+        	return;
+        }
+        try {
+		    String modelName = getMetadata().getFullName(modelID);
+		    ModelMetaData model = vdb.getModel(modelName);
+		    if(!model.isVisible()) {
+		        handleValidationError(DQPPlugin.Util.getString("ERR.018.005.0088", getMetadata().getFullName(group.getMetadataID()))); //$NON-NLS-1$
+		    }
+        } catch (TeiidComponentException e) {
+			handleException(e, group);
+		}
+    }
+
+    
+    /**
+     * Out of resources specified, return the subset for which the specified not have authorization to access.
+     */
+    public Set<String> getInaccessibleResources(DataPolicy.PermissionType action, Set<String> resources, Context context) {
+        if (!this.useEntitlements) {
+        	return Collections.emptySet();
+        }
+        
+        if (LogManager.isMessageToBeRecorded(LogConstants.CTX_AUDITLOGGING, MessageLevel.DETAIL)) {
+	        // Audit - request
+	    	AuditMessage msg = new AuditMessage(context.name(), "getInaccessibleResources-request", this.userName, resources.toArray(new String[resources.size()])); //$NON-NLS-1$
+	    	LogManager.logDetail(LogConstants.CTX_AUDITLOGGING, msg);
+        }
+        
+        HashSet<String> results = new HashSet<String>(resources);
+        
+		for(DataPolicy p:this.allowedPolicies.values()) {
+			DataPolicyMetadata policy = (DataPolicyMetadata)p;
+			
+			if (results.isEmpty()) {
+				break;
+			}
+			
+			Iterator<String> i = results.iterator();
+			while (i.hasNext()) {				
+				if (policy.allows(i.next(), action)) {
+					i.remove();
+				}
+			}
+		}
+
+		if (LogManager.isMessageToBeRecorded(LogConstants.CTX_AUDITLOGGING, MessageLevel.DETAIL)) {
+	        if (results.isEmpty()) {
+	        	AuditMessage msg = new AuditMessage(context.name(), "getInaccessibleResources-granted all", this.userName, resources.toArray(new String[resources.size()])); //$NON-NLS-1$
+	        	LogManager.logDetail(LogConstants.CTX_AUDITLOGGING, msg);
+	        } else {
+	        	AuditMessage msg = new AuditMessage(context.name(), "getInaccessibleResources-denied", this.userName, resources.toArray(new String[resources.size()])); //$NON-NLS-1$
+	        	LogManager.logDetail(LogConstants.CTX_AUDITLOGGING, msg);
+	        }
+		}
+        return results;
+    }    
+}

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-07-23 21:44:19 UTC (rev 2371)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -49,7 +49,6 @@
 import org.teiid.dqp.internal.process.multisource.MultiSourceCapabilitiesFinder;
 import org.teiid.dqp.internal.process.multisource.MultiSourceMetadataWrapper;
 import org.teiid.dqp.internal.process.multisource.MultiSourcePlanToProcessConverter;
-import org.teiid.dqp.internal.process.validator.AuthorizationValidationVisitor;
 import org.teiid.dqp.message.RequestID;
 import org.teiid.dqp.service.TransactionContext;
 import org.teiid.dqp.service.TransactionService;

Copied: trunk/engine/src/main/java/org/teiid/dqp/internal/process/TransactionServerImpl.java (from rev 2371, trunk/engine/src/main/java/org/teiid/dqp/internal/transaction/TransactionServerImpl.java)
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/TransactionServerImpl.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/TransactionServerImpl.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -0,0 +1,541 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.dqp.internal.process;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+import javax.resource.NotSupportedException;
+import javax.resource.spi.XATerminator;
+import javax.resource.spi.work.WorkException;
+import javax.resource.spi.work.WorkManager;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import org.teiid.adminapi.AdminException;
+import org.teiid.adminapi.AdminProcessingException;
+import org.teiid.adminapi.impl.TransactionMetadata;
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.core.util.Assertion;
+import org.teiid.dqp.DQPPlugin;
+import org.teiid.dqp.internal.process.DQPCore.FutureWork;
+import org.teiid.dqp.service.TransactionContext;
+import org.teiid.dqp.service.TransactionService;
+import org.teiid.dqp.service.TransactionContext.Scope;
+
+
+public class TransactionServerImpl implements TransactionService {
+
+    private static class TransactionMapping {
+
+        // (connection -> transaction for global and local)
+        private Map<String, TransactionContext> threadToTransactionContext = new HashMap<String, TransactionContext>();
+        // (MMXid -> global transactions keyed) 
+        private Map<Xid, TransactionContext> xidToTransactionContext = new HashMap<Xid, TransactionContext>();
+        
+        public synchronized TransactionContext getOrCreateTransactionContext(String threadId) {
+            TransactionContext tc = threadToTransactionContext.get(threadId);
+
+            if (tc == null) {
+                tc = new TransactionContext();
+                tc.setThreadId(threadId);
+                threadToTransactionContext.put(threadId, tc);
+            }
+
+            return tc;
+        }
+        
+        public synchronized TransactionContext getTransactionContext(String threadId) {
+            return threadToTransactionContext.get(threadId);
+        }
+
+        public synchronized TransactionContext getTransactionContext(XidImpl xid) {
+            return xidToTransactionContext.get(xid);
+        }
+        
+        public synchronized TransactionContext removeTransactionContext(String threadId) {
+            return threadToTransactionContext.remove(threadId);
+        }
+
+        public synchronized void removeTransactionContext(TransactionContext tc) {
+            if (tc.getXid() != null) {
+                this.xidToTransactionContext.remove(tc.getXid());
+            }
+            if (tc.getThreadId() != null) {
+                this.threadToTransactionContext.remove(tc.getThreadId());
+            }
+        }
+        
+        public synchronized void addTransactionContext(TransactionContext tc) {
+            if (tc.getXid() != null) {
+                this.xidToTransactionContext.put(tc.getXid(), tc);
+            }
+            if (tc.getThreadId() != null) {
+                this.threadToTransactionContext.put(tc.getThreadId(), tc);
+            }
+        }
+    }
+
+    private TransactionMapping transactions = new TransactionMapping();
+    
+    private XATerminator xaTerminator;
+    private TransactionManager transactionManager;
+    private WorkManager workManager;
+
+    public void setXaTerminator(XATerminator xaTerminator) {
+		this.xaTerminator = xaTerminator;
+	}
+    
+    public void setTransactionManager(TransactionManager transactionManager) {
+		this.transactionManager = transactionManager;
+	}
+    
+    public void setWorkManager(WorkManager workManager) {
+		this.workManager = workManager;
+	}
+
+    /**
+     * Global Transaction 
+     */
+	public int prepare(final String threadId, XidImpl xid, boolean singleTM) throws XATransactionException {
+        TransactionContext tc = checkXAState(threadId, xid, true, false);
+        if (!tc.getSuspendedBy().isEmpty()) {
+            throw new XATransactionException(XAException.XAER_PROTO, DQPPlugin.Util.getString("TransactionServer.suspended_exist", xid)); //$NON-NLS-1$
+        }		
+        
+        // In the container this pass though
+        if (singleTM) {        	    	
+	    	return XAResource.XA_RDONLY;
+        }
+        
+        try {
+        	return this.xaTerminator.prepare(tc.getXid());
+        } catch (XAException e) {
+            throw new XATransactionException(e);
+        }
+    }
+    
+    /**
+     * Global Transaction 
+     */    
+    public void commit(final String threadId, XidImpl xid, boolean onePhase, boolean singleTM) throws XATransactionException {
+    	TransactionContext tc = checkXAState(threadId, xid, true, false);  
+    	try {
+        	if (singleTM || (onePhase && XAResource.XA_RDONLY == prepare(threadId, xid, singleTM))) {
+        		return; //nothing to do
+        	}
+        	//TODO: we have no way of knowing for sure if we can safely use the onephase optimization
+        	this.xaTerminator.commit(tc.getXid(), false); 
+    	} catch (XAException e) {
+            throw new XATransactionException(e);
+        } finally {
+    		this.transactions.removeTransactionContext(tc);
+    	}
+    }
+    
+    /**
+     * Global Transaction 
+     */
+    public void rollback(final String threadId, XidImpl xid, boolean singleTM) throws XATransactionException {
+    	TransactionContext tc = checkXAState(threadId, xid, true, false);  
+    	try {
+    		// In the case of single TM, the container directly roll backs the sources.
+        	if (!singleTM) {
+        		this.xaTerminator.rollback(tc.getXid());
+        	}
+    	} catch (XAException e) {
+            throw new XATransactionException(e);
+        } finally {
+    		this.transactions.removeTransactionContext(tc);
+    	}
+    }
+
+    /**
+     * Global Transaction 
+     */    
+    public Xid[] recover(int flag, boolean singleTM) throws XATransactionException {
+    	// In case of single TM, container knows this list.
+    	if (singleTM) {
+    		return new Xid[0];
+    	}
+    	
+    	try {
+			return this.xaTerminator.recover(flag);
+		} catch (XAException e) {
+			throw new XATransactionException(e);
+		}
+    }
+
+    /**
+     * Global Transaction 
+     */    
+    public void forget(final String threadId, XidImpl xid, boolean singleTM) throws XATransactionException {
+    	TransactionContext tc = checkXAState(threadId, xid, true, false); 
+        try {
+        	if (singleTM) {
+        		return;
+        	}
+            this.xaTerminator.forget(xid);
+        } catch (XAException err) {
+            throw new XATransactionException(err);
+        } finally {
+        	this.transactions.removeTransactionContext(tc);
+        }
+    }
+
+    /**
+     * Global Transaction 
+     */
+    public void start(final String threadId, final XidImpl xid, int flags, int timeout, boolean singleTM) throws XATransactionException {
+        
+        TransactionContext tc = null;
+
+        switch (flags) {
+            case XAResource.TMNOFLAGS: {
+                try {
+					checkXAState(threadId, xid, false, false);
+					tc = transactions.getOrCreateTransactionContext(threadId);
+					if (tc.getTransactionType() != TransactionContext.Scope.NONE) {
+					    throw new XATransactionException(XAException.XAER_PROTO, DQPPlugin.Util.getString("TransactionServer.existing_transaction")); //$NON-NLS-1$
+					}
+					tc.setTransactionTimeout(timeout);
+					tc.setXid(xid);
+					tc.setTransactionType(TransactionContext.Scope.GLOBAL);
+					if (singleTM) {
+						tc.setTransaction(transactionManager.getTransaction());
+						assert tc.getTransaction() != null;
+					} else {
+						FutureWork<Transaction> work = new FutureWork<Transaction>(new Callable<Transaction>() {
+							@Override
+							public Transaction call() throws Exception {
+								return transactionManager.getTransaction();
+							}
+						}, 0);
+						workManager.doWork(work, WorkManager.INDEFINITE, tc, null);
+						tc.setTransaction(work.getResult().get());
+					}
+				} catch (NotSupportedException e) {
+					throw new XATransactionException(e, XAException.XAER_INVAL);
+				} catch (WorkException e) {
+					throw new XATransactionException(e, XAException.XAER_INVAL);
+				} catch (InterruptedException e) {
+					throw new XATransactionException(e, XAException.XAER_INVAL);
+				} catch (ExecutionException e) {
+					throw new XATransactionException(e, XAException.XAER_INVAL);
+				} catch (SystemException e) {
+					throw new XATransactionException(e, XAException.XAER_INVAL);
+				}
+                break;
+            }
+            case XAResource.TMJOIN:
+            case XAResource.TMRESUME: {
+                tc = checkXAState(threadId, xid, true, false);
+                TransactionContext threadContext = transactions.getOrCreateTransactionContext(threadId);
+                if (threadContext.getTransactionType() != TransactionContext.Scope.NONE) {
+                    throw new XATransactionException(XAException.XAER_PROTO, DQPPlugin.Util.getString("TransactionServer.existing_transaction")); //$NON-NLS-1$
+                }
+                
+                if (flags == XAResource.TMRESUME && !tc.getSuspendedBy().remove(threadId)) {
+                    throw new XATransactionException(XAException.XAER_PROTO, DQPPlugin.Util.getString("TransactionServer.resume_failed", new Object[] {xid, threadId})); //$NON-NLS-1$
+                }
+                break;
+            }
+            default:
+                throw new XATransactionException(XAException.XAER_INVAL, DQPPlugin.Util.getString("TransactionServer.unknown_flags")); //$NON-NLS-1$
+        }
+
+        tc.setThreadId(threadId);
+        transactions.addTransactionContext(tc);
+    }
+
+    /**
+     * Global Transaction 
+     */    
+    public void end(final String threadId, XidImpl xid, int flags, boolean singleTM) throws XATransactionException {
+        TransactionContext tc = checkXAState(threadId, xid, true, true);
+        try {
+            switch (flags) {
+                case XAResource.TMSUSPEND: {
+                    tc.getSuspendedBy().add(threadId);
+                    break;
+                }
+                case XAResource.TMSUCCESS: {
+                    //TODO: should close all statements
+                    break;
+                }
+                case XAResource.TMFAIL: {
+                	cancelTransactions(threadId, false);
+                    break;
+                }
+                default:
+                    throw new XATransactionException(XAException.XAER_INVAL, DQPPlugin.Util.getString("TransactionServer.unknown_flags")); //$NON-NLS-1$
+            }
+        } finally {
+            tc.setThreadId(null);
+            transactions.removeTransactionContext(threadId);
+        }
+    }
+
+    private TransactionContext checkXAState(final String threadId, final XidImpl xid, boolean transactionExpected, boolean threadBound) throws XATransactionException {
+        TransactionContext tc = transactions.getTransactionContext(xid);
+        
+        if (transactionExpected && tc == null) {
+            throw new XATransactionException(XAException.XAER_NOTA, DQPPlugin.Util.getString("TransactionServer.no_global_transaction", xid)); //$NON-NLS-1$
+        } else if (!transactionExpected) {
+            if (tc != null) {
+                throw new XATransactionException(XAException.XAER_DUPID, DQPPlugin.Util.getString("TransactionServer.existing_global_transaction", new Object[] {xid})); //$NON-NLS-1$
+            }
+            if (!threadBound) {
+                tc = transactions.getOrCreateTransactionContext(threadId);
+                if (tc.getTransactionType() != TransactionContext.Scope.NONE) {
+                    throw new XATransactionException(XAException.XAER_PROTO, DQPPlugin.Util.getString("TransactionServer.existing_transaction", new Object[] {xid, threadId})); //$NON-NLS-1$
+                }
+            }
+            return null;
+        } 
+        
+        if (threadBound) {
+            if (!threadId.equals(tc.getThreadId())) {
+                throw new XATransactionException(XAException.XAER_PROTO, DQPPlugin.Util.getString("TransactionServer.wrong_transaction", xid)); //$NON-NLS-1$
+            }
+        } else if (tc.getThreadId() != null) {
+            throw new XATransactionException(XAException.XAER_PROTO, DQPPlugin.Util.getString("TransactionServer.concurrent_transaction", xid)); //$NON-NLS-1$
+        }
+        
+        return tc;
+    }
+
+    private TransactionContext checkLocalTransactionState(String threadId, boolean transactionExpected) 
+    	throws XATransactionException {
+
+        final TransactionContext tc = transactions.getOrCreateTransactionContext(threadId);
+
+        try {
+	        if (tc.getTransactionType() != TransactionContext.Scope.NONE) {
+	            if (tc.getTransactionType() != TransactionContext.Scope.LOCAL) {
+	                throw new InvalidTransactionException(DQPPlugin.Util.getString("TransactionServer.existing_transaction")); //$NON-NLS-1$
+	            }
+	            if (!transactionExpected) {
+	            	throw new InvalidTransactionException(DQPPlugin.Util.getString("TransactionServer.existing_transaction")); //$NON-NLS-1$
+	            }
+	            transactionManager.resume(tc.getTransaction());
+	        } else if (transactionExpected) {
+	        	throw new InvalidTransactionException(DQPPlugin.Util.getString("TransactionServer.no_transaction", threadId)); //$NON-NLS-1$
+	        }
+        } catch (InvalidTransactionException e) {
+        	throw new XATransactionException(e);
+		} catch (SystemException e) {
+        	throw new XATransactionException(e);
+		}
+        return tc;
+    }
+    
+    private void beginDirect(TransactionContext tc) throws XATransactionException {
+		try {
+			transactionManager.begin();
+			Transaction tx = transactionManager.suspend();
+			tc.setTransaction(tx);
+			tc.setCreationTime(System.currentTimeMillis());
+        } catch (javax.transaction.NotSupportedException err) {
+            throw new XATransactionException(err);
+        } catch (SystemException err) {
+            throw new XATransactionException(err);
+        }
+	}
+	
+	private void commitDirect(TransactionContext context)
+			throws XATransactionException {
+		try {
+			transactionManager.commit();
+		} catch (SecurityException e) {
+			throw new XATransactionException(e);
+		} catch (RollbackException e) {
+			throw new XATransactionException(e);
+		} catch (HeuristicMixedException e) {
+			throw new XATransactionException(e);
+		} catch (HeuristicRollbackException e) {
+			throw new XATransactionException(e);
+		} catch (SystemException e) {
+			throw new XATransactionException(e);
+		} finally {
+			transactions.removeTransactionContext(context);
+		}
+	}
+
+	private void rollbackDirect(TransactionContext tc)
+			throws XATransactionException {
+		try {
+    		this.transactionManager.rollback();
+		} catch (SecurityException e) {
+			throw new XATransactionException(e);
+		} catch (SystemException e) {
+			throw new XATransactionException(e);
+		} finally {
+            transactions.removeTransactionContext(tc);
+        }
+	}
+	
+	public void suspend(TransactionContext context) throws XATransactionException {
+		try {
+			this.transactionManager.suspend();
+		} catch (SystemException e) {
+			throw new XATransactionException(e);
+		}
+	}
+	
+	public void resume(TransactionContext context) throws XATransactionException {
+		try {
+			this.transactionManager.resume(context.getTransaction());
+		} catch (InvalidTransactionException e) {
+			throw new XATransactionException(e);
+		} catch (SystemException e) {
+			throw new XATransactionException(e);
+		}
+	}
+
+    /**
+     * Local Transaction 
+     */
+    public TransactionContext begin(String threadId) throws XATransactionException {
+        TransactionContext tc = checkLocalTransactionState(threadId, false);
+        beginDirect(tc);
+        tc.setTransactionType(TransactionContext.Scope.LOCAL);
+        return tc;
+    }
+
+    /**
+     * Local Transaction 
+     */    
+    public void commit(String threadId) throws XATransactionException {
+        TransactionContext tc = checkLocalTransactionState(threadId, true);
+        commitDirect(tc);
+    }
+
+    /**
+     * Local Transaction 
+     */    
+    public void rollback(String threadId) throws XATransactionException {
+        TransactionContext tc = checkLocalTransactionState(threadId, true);
+        rollbackDirect(tc);
+    }
+
+    public TransactionContext getOrCreateTransactionContext(String threadId) {
+        return transactions.getOrCreateTransactionContext(threadId);
+    }
+
+    /**
+     * Request level transaction
+     */
+    public TransactionContext begin(TransactionContext context) throws XATransactionException{
+        if (context.getTransactionType() != TransactionContext.Scope.NONE) {
+            throw new XATransactionException(DQPPlugin.Util.getString("TransactionServer.existing_transaction")); //$NON-NLS-1$
+        }
+        beginDirect(context);
+        context.setTransactionType(TransactionContext.Scope.REQUEST);
+        return context;
+    }
+
+    /**
+     * Request level transaction
+     */    
+    public TransactionContext commit(TransactionContext context) throws XATransactionException {
+        Assertion.assertTrue(context.getTransactionType() == TransactionContext.Scope.REQUEST);
+        commitDirect(context);
+        return context;
+    }
+
+    /**
+     * Request level transaction
+     */    
+    public TransactionContext rollback(TransactionContext context) throws XATransactionException {
+        Assertion.assertTrue(context.getTransactionType() == TransactionContext.Scope.REQUEST);
+        rollbackDirect(context);
+        return context;      
+    }
+
+    public void cancelTransactions(String threadId, boolean requestOnly) throws XATransactionException {
+        TransactionContext tc = transactions.getTransactionContext(threadId);
+        
+        if (tc == null || tc.getTransactionType() == TransactionContext.Scope.NONE 
+        		|| (requestOnly && tc.getTransactionType() != TransactionContext.Scope.REQUEST)) {
+            return;
+        }
+        
+        try {
+            tc.getTransaction().setRollbackOnly();
+		} catch (SystemException e) {
+			throw new XATransactionException(e);
+		}
+    }
+
+	@Override
+	public Collection<org.teiid.adminapi.Transaction> getTransactions() {
+		Set<TransactionContext> txnSet = Collections.newSetFromMap(new IdentityHashMap<TransactionContext, Boolean>());
+		synchronized (this.transactions) {
+			txnSet.addAll(this.transactions.threadToTransactionContext.values());
+			txnSet.addAll(this.transactions.xidToTransactionContext.values());
+		}
+		Collection<org.teiid.adminapi.Transaction> result = new ArrayList<org.teiid.adminapi.Transaction>(txnSet.size());
+		for (TransactionContext transactionContext : txnSet) {
+			if (transactionContext.getTransactionType() == Scope.NONE) {
+				continue;
+			}
+			TransactionMetadata txnImpl = new TransactionMetadata();
+			txnImpl.setAssociatedSession(Long.parseLong(transactionContext.getThreadId()));
+			txnImpl.setCreatedTime(transactionContext.getCreationTime());
+			txnImpl.setScope(transactionContext.getTransactionType().toString());
+			txnImpl.setId(transactionContext.getTransactionId());
+			result.add(txnImpl);
+		}
+		return result;
+	}
+	
+	@Override
+	public void terminateTransaction(String threadId) throws AdminException {
+		if (threadId == null) {
+			return;
+		}
+		try {
+			cancelTransactions(threadId, false);
+		} catch (XATransactionException e) {
+			throw new AdminProcessingException(e);
+		}
+	}
+	
+}

Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java	2010-07-23 21:44:19 UTC (rev 2371)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -58,7 +58,6 @@
  * A Teiid Temp Table
  * TODO: an update will not happen unless the tuplesource is accessed
  * TODO: better handling for blocked exceptions (should be rare)
- * TODO: non-pk updates/deletes through the browser 
  */
 class TempTable {
 	
@@ -166,15 +165,11 @@
 	}
 
 	public TupleSource createTupleSource(List<Criteria> conditions, OrderBy orderBy) throws TeiidComponentException {
-		return createTupleSource(conditions, orderBy, true);
-	}
-	
-	private TupleSource createTupleSource(List<Criteria> conditions, OrderBy orderBy, boolean filterRowId) throws TeiidComponentException {
+		TupleBrowser browser = createTupleBrower(conditions, orderBy);
 		TupleBuffer tb = bm.createTupleBuffer(columns, sessionID, TupleSourceType.PROCESSOR);
-		TupleBrowser browser = tree.browse(null, null, OrderBy.ASC);
 		List next = null;
 		while ((next = browser.next()) != null) {
-			if (rowId != null && filterRowId) {
+			if (rowId != null) {
 				next = next.subList(1, next.size());
 			}
 			tb.addTuple(next);
@@ -183,6 +178,10 @@
 		return tb.createIndexedTupleSource(true);
 	}
 	
+	private TupleBrowser createTupleBrower(List<Criteria> conditions, OrderBy orderBy) throws TeiidComponentException {
+		return tree.browse(null, null, OrderBy.ASC);
+	}
+	
 	public int getRowCount() {
 		return tree.getRowCount();
 	}
@@ -221,11 +220,37 @@
         };
         return uts;
     }
+	
+	private TupleSource asTupleSource(final TupleBrowser browser) {
+		return new TupleSource() {
+			
+			@Override
+			public List<?> nextTuple() throws TeiidComponentException,
+					TeiidProcessingException {
+				return browser.next();
+			}
+			
+			@Override
+			public List<? extends Expression> getSchema() {
+				return columns;
+			}
+			
+			@Override
+			public void closeSource() {
+				
+			}
+			
+			@Override
+			public int available() {
+				return 0;
+			}
+		};
+	}
 		
 	public TupleSource update(Criteria crit, final SetClauseList update) throws TeiidComponentException {
 		final boolean primaryKeyChangePossible = canChangePrimaryKey(update);
-		
-		UpdateTupleSource uts = new UpdateTupleSource(crit, createTupleSource(null, null, false)) {
+		final TupleBrowser browser = createTupleBrower(null, null);
+		UpdateTupleSource uts = new UpdateTupleSource(crit, asTupleSource(browser)) {
 			
 			protected TupleBuffer changeSet;
 			protected TupleSource changeSetProcessor;
@@ -239,13 +264,14 @@
     				newTuple.set((Integer)lookup.get(entry.getKey()), eval.evaluate(entry.getValue(), tuple));
     			}
     			if (primaryKeyChangePossible) {
+    				browser.removed();
     				deleteTuple(tuple);
     				if (changeSet == null) {
     					changeSet = bm.createTupleBuffer(columns, sessionID, TupleSourceType.PROCESSOR);
     				}
     				changeSet.addTuple(newTuple);
     			} else {
-    				updateTuple(newTuple);
+    				browser.update(newTuple);
     			}
 			}
 			
@@ -312,11 +338,13 @@
 	}
 	
 	public TupleSource delete(Criteria crit) throws TeiidComponentException {
-		UpdateTupleSource uts = new UpdateTupleSource(crit, createTupleSource(null, null, false)) {
+		final TupleBrowser browser = createTupleBrower(null, null);
+		UpdateTupleSource uts = new UpdateTupleSource(crit, asTupleSource(browser)) {
 			@Override
 			protected void tuplePassed(List tuple)
 					throws ExpressionEvaluationException,
 					BlockedException, TeiidComponentException {
+				browser.removed();
 				deleteTuple(tuple);
 			}
 			

Modified: trunk/engine/src/test/java/org/teiid/common/queue/TestThreadReuseExecutor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/common/queue/TestThreadReuseExecutor.java	2010-07-23 21:44:19 UTC (rev 2371)
+++ trunk/engine/src/test/java/org/teiid/common/queue/TestThreadReuseExecutor.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -154,7 +154,7 @@
     	}, 0, 30, TimeUnit.MILLISECONDS);
     	Thread.sleep(120);
     	future.cancel(true);
-    	assertEquals(2, result.size());
+    	assertTrue(result.size() < 3);
     }
     
     @Test public void testFailingWork() throws Exception {

Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeTransactionService.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeTransactionService.java	2010-07-23 21:44:19 UTC (rev 2371)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/datamgr/FakeTransactionService.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -27,7 +27,7 @@
 
 import org.teiid.common.queue.FakeWorkManager;
 import org.teiid.core.util.SimpleMock;
-import org.teiid.dqp.internal.transaction.TransactionServerImpl;
+import org.teiid.dqp.internal.process.TransactionServerImpl;
 
 
 public class FakeTransactionService extends TransactionServerImpl {

Copied: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java (from rev 2371, trunk/engine/src/test/java/org/teiid/dqp/internal/process/validator/TestAuthorizationValidationVisitor.java)
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java	                        (rev 0)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestAuthorizationValidationVisitor.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -0,0 +1,305 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.dqp.internal.process;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.teiid.adminapi.DataPolicy;
+import org.teiid.adminapi.DataPolicy.PermissionType;
+import org.teiid.adminapi.impl.DataPolicyMetadata;
+import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.adminapi.impl.DataPolicyMetadata.PermissionMetaData;
+import org.teiid.api.exception.query.QueryParserException;
+import org.teiid.api.exception.query.QueryResolverException;
+import org.teiid.api.exception.query.QueryValidatorException;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.dqp.internal.process.AuthorizationValidationVisitor;
+import org.teiid.dqp.internal.process.Request;
+import org.teiid.query.metadata.QueryMetadataInterface;
+import org.teiid.query.parser.QueryParser;
+import org.teiid.query.resolver.QueryResolver;
+import org.teiid.query.sql.lang.Command;
+import org.teiid.query.sql.symbol.Symbol;
+import org.teiid.query.unittest.FakeMetadataFactory;
+import org.teiid.query.validator.Validator;
+import org.teiid.query.validator.ValidatorFailure;
+import org.teiid.query.validator.ValidatorReport;
+
+
+public class TestAuthorizationValidationVisitor extends TestCase {
+
+    public static final String CONN_ID = "connID"; //$NON-NLS-1$
+
+    /**
+     * Constructor for TestAuthorizationValidationVisitor.
+     * @param name
+     */
+    public TestAuthorizationValidationVisitor(String name) {
+        super(name);
+    }
+    
+    PermissionMetaData addResource(PermissionType type, boolean flag, String resource) {
+    	PermissionMetaData p = new PermissionMetaData();
+    	p.setResourceName(resource);
+    	switch(type) {
+    	case CREATE:
+    		p.setAllowCreate(flag);
+    		break;
+    	case DELETE:
+    		p.setAllowDelete(flag);
+    		break;
+    	case READ:
+    		p.setAllowRead(flag);
+    		break;
+    	case UPDATE:
+    		p.setAllowUpdate(flag);
+    		break;
+    	}
+    	return p;    	
+    }
+    PermissionMetaData addResource(PermissionType type, String resource) {
+    	return addResource(type, true, resource);
+    }
+
+    private DataPolicyMetadata exampleAuthSvc1() {
+    	DataPolicyMetadata svc = new DataPolicyMetadata();
+    	svc.setName("test"); //$NON-NLS-1$
+        
+        // pm1.g1
+        svc.addPermission(addResource(PermissionType.DELETE, "pm1.g1")); //$NON-NLS-1$
+        
+        svc.addPermission(addResource(DataPolicy.PermissionType.READ, "pm1.g1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.READ, "pm1.g1.e1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.READ, false, "pm1.g1.e2")); //$NON-NLS-1$
+
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g1.e1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g1.e2")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g1.e3")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g1.e4")); //$NON-NLS-1$
+
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, false, "pm1.g1.e1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g1.e2")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g1.e3")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g1.e4")); //$NON-NLS-1$
+        
+
+        // pm1.g2
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g2")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, false, "pm1.g2.e1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g2.e2")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g2.e3")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g2.e4")); //$NON-NLS-1$
+
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g2")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, false, "pm1.g2.e1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g2.e2")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g2.e3")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.UPDATE, "pm1.g2.e4")); //$NON-NLS-1$
+
+        // pm1.g4
+        svc.addPermission(addResource(DataPolicy.PermissionType.DELETE, "pm1.g4")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.DELETE, "pm1.g4.e1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.DELETE, "pm1.g4.e2")); //$NON-NLS-1$
+
+        // pm1.sq2
+        svc.addPermission(addResource(DataPolicy.PermissionType.READ, "pm1.sq1")); //$NON-NLS-1$
+        
+        return svc;
+    }
+    
+    //allow by default
+    private DataPolicyMetadata exampleAuthSvc2() {
+    	DataPolicyMetadata svc = new DataPolicyMetadata();
+    	svc.setName("test"); //$NON-NLS-1$
+    	
+    	svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm1.g2")); //$NON-NLS-1$
+    	svc.addPermission(addResource(DataPolicy.PermissionType.READ, "pm1.g2")); //$NON-NLS-1$
+    	svc.addPermission(addResource(DataPolicy.PermissionType.READ, "pm2.g1")); //$NON-NLS-1$
+        
+    	// pm2.g2
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm2.g2.e1")); //$NON-NLS-1$
+        
+        // pm3.g2
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm3.g2.e1")); //$NON-NLS-1$
+        svc.addPermission(addResource(DataPolicy.PermissionType.CREATE, "pm3.g2.e2")); //$NON-NLS-1$
+        
+        return svc;
+    }
+
+    private void helpTest(DataPolicyMetadata policy, String sql, QueryMetadataInterface metadata, String[] expectedInaccesible, VDBMetaData vdb) throws QueryParserException, QueryResolverException, TeiidComponentException {
+        QueryParser parser = QueryParser.getQueryParser();
+        Command command = parser.parseCommand(sql);
+        QueryResolver.resolveCommand(command, metadata);
+        
+        vdb.addAttchment(QueryMetadataInterface.class, metadata);
+        
+        HashMap<String, DataPolicy> policies = new HashMap<String, DataPolicy>();
+        policies.put(policy.getName(), policy);
+        
+        AuthorizationValidationVisitor visitor = new AuthorizationValidationVisitor(vdb, true, policies, "test"); //$NON-NLS-1$
+        ValidatorReport report = Validator.validate(command, metadata, visitor);
+        if(report.hasItems()) {
+            ValidatorFailure firstFailure = (ValidatorFailure) report.getItems().iterator().next();
+            
+            // strings
+            Set expected = new HashSet(Arrays.asList(expectedInaccesible));
+            // elements
+            Set actual = new HashSet();
+            Iterator iter = firstFailure.getInvalidObjects().iterator();
+            while(iter.hasNext()) {
+                Symbol symbol = (Symbol) iter.next();
+                actual.add(symbol.getName());
+            }
+            assertEquals(expected, actual);
+        } else if(expectedInaccesible.length > 0) {
+            fail("Expected inaccessible objects, but got none.");                 //$NON-NLS-1$
+        }
+    }
+    
+    public void testEverythingAccessible() throws Exception {
+        helpTest(exampleAuthSvc1(), "SELECT e1 FROM pm1.g1", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+    
+    public void testEverythingAccessible1() throws Exception {
+        helpTest(exampleAuthSvc1(), "SELECT e1 FROM (select e1 from pm1.g1) x", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+    
+    public void testEverythingAccessible2() throws Exception {
+        helpTest(exampleAuthSvc1(), "SELECT lookup('pm1.g1', 'e1', 'e1', '1'), e1 FROM (select e1 from pm1.g1) x", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+
+    public void testInaccesibleElement() throws Exception {        
+        helpTest(exampleAuthSvc1(), "SELECT e2 FROM pm1.g1", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testInaccesibleElement2() throws Exception {        
+        helpTest(exampleAuthSvc1(), "SELECT lookup('pm1.g1', 'e1', 'e2', '1')", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testInaccesibleGroup() throws Exception {        
+        helpTest(exampleAuthSvc1(), "SELECT e1 FROM pm1.g2", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g2", "pm1.g2.e1"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    public void testInsert() throws Exception {        
+        helpTest(exampleAuthSvc1(), "INSERT INTO pm1.g1 (e1, e2, e3, e4) VALUES ('x', 5, {b'true'}, 1.0)", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+
+    public void testInsertInaccessible() throws Exception {        
+        helpTest(exampleAuthSvc1(), "INSERT INTO pm1.g2 (e1, e2, e3, e4) VALUES ('x', 5, {b'true'}, 1.0)", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testUpdate() throws Exception {        
+        helpTest(exampleAuthSvc1(), "UPDATE pm1.g1 SET e2 = 5", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+
+    public void testUpdateCriteriaInaccessibleForRead() throws Exception {        
+        helpTest(exampleAuthSvc1(), "UPDATE pm1.g2 SET e2 = 5 WHERE e1 = 'x'", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testUpdateElementInaccessibleForUpdate() throws Exception {        
+        helpTest(exampleAuthSvc1(), "UPDATE pm1.g1 SET e1 = 5 WHERE e1 = 'x'", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g1.e1"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testDelete() throws Exception {        
+        helpTest(exampleAuthSvc1(), "DELETE FROM pm1.g1", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+
+    public void testDeleteCriteriaInaccesibleForRead() throws Exception {        
+        helpTest(exampleAuthSvc1(), "DELETE FROM pm1.g2 WHERE e1 = 'x'", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g2.e1"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testDeleteInaccesibleGroup() throws Exception {        
+        helpTest(exampleAuthSvc1(), "DELETE FROM pm1.g3", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g3"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testProc() throws Exception {
+        helpTest(exampleAuthSvc1(), "EXEC pm1.sq1()", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB());         //$NON-NLS-1$
+    }
+
+    public void testProcInaccesible() throws Exception {
+        helpTest(exampleAuthSvc1(), "EXEC pm1.sq2('xyz')", FakeMetadataFactory.example1Cached(), new String[] {"pm1.sq2"}, FakeMetadataFactory.example1VDB());         //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    public void testSelectIntoEverythingAccessible() throws Exception {
+        helpTest(exampleAuthSvc2(), "SELECT e1, e2, e3, e4 INTO pm1.g2 FROM pm2.g1", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+
+    public void testSelectIntoTarget_e1_NotAccessible() throws Exception {
+        helpTest(exampleAuthSvc2(), "SELECT e1, e2, e3, e4 INTO pm2.g2 FROM pm2.g1", FakeMetadataFactory.example1Cached(), new String[] {"pm2.g2.e2","pm2.g2.e4","pm2.g2.e3"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    }
+
+    public void testSelectIntoTarget_e1e2_NotAccessible() throws Exception {
+        helpTest(exampleAuthSvc2(), "SELECT e1, e2, e3, e4 INTO pm3.g2 FROM pm2.g1", FakeMetadataFactory.example1Cached(), new String[] {"pm3.g2.e4", "pm3.g2.e3"},FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+    
+    public void testTempTableSelectInto() throws Exception {
+        helpTest(exampleAuthSvc1(), "SELECT e1 INTO #temp FROM pm1.g1", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+    
+    public void testTempTableSelectInto1() throws Exception {
+        helpTest(exampleAuthSvc1(), "SELECT e1, e2 INTO #temp FROM pm1.g1", FakeMetadataFactory.example1Cached(), new String[] {"pm1.g1.e2"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testTempTableInsert() throws Exception {
+        helpTest(exampleAuthSvc2(), "insert into #temp (e1, e2, e3, e4) values ('1', '2', '3', '4')", FakeMetadataFactory.example1Cached(), new String[] {}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$
+    }
+
+    public void testXMLAccessible() throws Exception {
+        helpTest(exampleAuthSvc2(), "select * from xmltest.doc1", FakeMetadataFactory.example1Cached(), new String[] {"xmltest.doc1"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public void testXMLInAccessible() throws Exception {
+        helpTest(exampleAuthSvc1(), "select * from xmltest.doc1", FakeMetadataFactory.example1Cached(), new String[] {"xmltest.doc1"}, FakeMetadataFactory.example1VDB()); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+	private void helpTestLookupVisibility(boolean visible) throws QueryParserException, QueryValidatorException, TeiidComponentException {
+		VDBMetaData vdb = FakeMetadataFactory.example1VDB();
+		vdb.getModel("pm1").setVisible(visible); //$NON-NLS-1$
+		AuthorizationValidationVisitor mvvv = new AuthorizationValidationVisitor(vdb, false, new HashMap<String, DataPolicy>(), "test"); //$NON-NLS-1$
+		String sql = "select lookup('pm1.g1', 'e1', 'e2', 1)"; //$NON-NLS-1$
+		Command command = QueryParser.getQueryParser().parseCommand(sql);
+		Request.validateWithVisitor(mvvv, FakeMetadataFactory.example1Cached(), command);
+	}
+	
+	public void testLookupVisibility() throws Exception {
+		helpTestLookupVisibility(true);
+	}
+	
+	public void testLookupVisibilityFails() throws Exception {
+		try {
+			helpTestLookupVisibility(false);
+			fail("expected exception"); //$NON-NLS-1$
+		} catch (QueryValidatorException e) {
+			assertEquals("Group does not exist: pm1.g1", e.getMessage()); //$NON-NLS-1$
+		}
+	}
+
+}

Copied: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestTransactionServer.java (from rev 2371, trunk/engine/src/test/java/org/teiid/dqp/internal/transaction/TestTransactionServer.java)
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestTransactionServer.java	                        (rev 0)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestTransactionServer.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -0,0 +1,399 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.dqp.internal.process;
+
+import static org.junit.Assert.*;
+
+import javax.resource.spi.XATerminator;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.teiid.adminapi.Transaction;
+import org.teiid.client.xa.XATransactionException;
+import org.teiid.client.xa.XidImpl;
+import org.teiid.common.queue.FakeWorkManager;
+import org.teiid.dqp.internal.process.TransactionServerImpl;
+import org.teiid.dqp.service.TransactionContext;
+
+public class TestTransactionServer {
+
+    private TransactionServerImpl server;
+    private XATerminator xaTerminator;
+    private TransactionManager tm;
+	private javax.transaction.Transaction txn;
+    
+    private static final String THREAD1 = "1"; //$NON-NLS-1$
+    private static final String THREAD2 = "2"; //$NON-NLS-1$
+
+    private static final XidImpl XID1 = new XidImpl(0, new byte[] {
+        1
+    }, new byte[0]);
+    private static final XidImpl XID2 = new XidImpl(0, new byte[] {
+        2
+    }, new byte[0]);
+
+    @Before public void setUp() throws Exception {
+        server = new TransactionServerImpl();
+        xaTerminator = Mockito.mock(XATerminator.class);
+        tm = Mockito.mock(TransactionManager.class);
+        txn = Mockito.mock(javax.transaction.Transaction.class);
+        Mockito.stub(tm.getTransaction()).toReturn(txn);
+        Mockito.stub(tm.suspend()).toReturn(txn);
+        server.setXaTerminator(xaTerminator);
+        server.setTransactionManager(tm);
+        server.setWorkManager(new FakeWorkManager());
+    }
+
+    /**
+     * once in a local, cannot start a global
+     */
+    @Test public void testTransactionExclusion() throws Exception {
+        server.begin(THREAD1);
+
+        try {
+            server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100, false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Client thread already involved in a transaction. Transaction nesting is not supported. The current transaction must be completed first.", //$NON-NLS-1$
+                         ex.getMessage());
+        }
+    }
+
+    /**
+     * once in a global, cannot start a local
+     */
+    @Test public void testTransactionExclusion1() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100, false);
+
+        try {
+            server.begin(THREAD1);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Client thread already involved in a transaction. Transaction nesting is not supported. The current transaction must be completed first.", //$NON-NLS-1$
+                         ex.getMessage());
+        }
+    }
+
+    /**
+     * global can only be started once
+     */
+    @Test public void testTransactionExclusion2() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+
+        try {
+            server.start(THREAD2, XID1, XAResource.TMNOFLAGS, 100,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Global transaction Teiid-Xid global:1 branch:null format:0 already exists.", ex.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * global cannot be nested
+     */
+    @Test public void testTransactionExclusion3() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+
+        try {
+            server.start(THREAD1, XID2, XAResource.TMNOFLAGS, 100,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Client thread already involved in a transaction. Transaction nesting is not supported. The current transaction must be completed first.", //$NON-NLS-1$
+                         ex.getMessage());
+        }
+    }
+
+    /**
+     * local cannot be nested
+     */
+    @Test public void testTransactionExclusion4() throws Exception {
+        server.begin(THREAD1);
+
+        try {
+            server.begin(THREAD1);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Client thread already involved in a transaction. Transaction nesting is not supported. The current transaction must be completed first.", //$NON-NLS-1$
+                         ex.getMessage());
+        }
+    }
+    
+    /**
+     * global cannot be nested
+     */
+    @Test public void testTransactionExclusion5() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+        server.start(THREAD2, XID2, XAResource.TMNOFLAGS, 100,false);
+        server.end(THREAD2, XID2, XAResource.TMSUCCESS,false);
+
+        try {
+            server.start(THREAD1, XID2, XAResource.TMJOIN, 100,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Client thread already involved in a transaction. Transaction nesting is not supported. The current transaction must be completed first.", //$NON-NLS-1$
+                         ex.getMessage());
+        }
+    }
+
+    @Test public void testLocalCommit() throws Exception {
+        server.begin(THREAD1);
+        server.commit(THREAD1);
+        
+        Mockito.verify(tm).commit();
+
+        try {
+            server.commit(THREAD1);
+        } catch (XATransactionException e) {
+            assertEquals("No transaction found for client 1.", e.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    @Test public void testTwoPhaseCommit() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+    	server.end(THREAD1, XID1, XAResource.TMSUCCESS, false);
+        server.commit(THREAD1, XID1, false, false);
+        
+        Mockito.verify(xaTerminator).commit(XID1, false);
+    }     
+    
+    @Test public void testLocalRollback() throws Exception {
+        server.begin(THREAD1);
+        server.rollback(THREAD1);
+        Mockito.verify(tm).rollback();
+        
+        try {
+            server.rollback(THREAD1);
+        } catch (XATransactionException e) {
+            assertEquals("No transaction found for client 1.", e.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    @Test public void testConcurrentEnlistment() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+
+        try {
+            server.start(THREAD1, XID1, XAResource.TMJOIN, 100,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Concurrent enlistment in global transaction Teiid-Xid global:1 branch:null format:0 is not supported.", //$NON-NLS-1$
+                         ex.getMessage());
+        }
+    }
+
+    @Test public void testSuspend() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+        server.end(THREAD1, XID1, XAResource.TMSUSPEND,false);
+
+        try {
+            server.end(THREAD1, XID1, XAResource.TMSUSPEND,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Client is not currently enlisted in transaction Teiid-Xid global:1 branch:null format:0.", ex.getMessage()); //$NON-NLS-1$
+        }
+    }
+    
+    @Test public void testSuspendResume() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+        server.end(THREAD1, XID1, XAResource.TMSUSPEND,false);
+        server.start(THREAD1, XID1, XAResource.TMRESUME, 100,false);
+        server.end(THREAD1, XID1, XAResource.TMSUSPEND,false);
+
+        try {
+            server.start(THREAD2, XID1, XAResource.TMRESUME, 100,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Cannot resume, transaction Teiid-Xid global:1 branch:null format:0 was not suspended by client 2.", ex.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    @Test public void testUnknownFlags() throws Exception {
+        try {
+            server.start(THREAD1, XID1, Integer.MAX_VALUE, 100,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Unknown flags", ex.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    @Test public void testUnknownGlobalTransaction() throws Exception {
+        try {
+            server.end(THREAD1, XID1, XAResource.TMSUCCESS,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("No global transaction found for Teiid-Xid global:1 branch:null format:0.", ex.getMessage()); //$NON-NLS-1$
+        }
+    }
+    
+    @Test public void testPrepareWithSuspended() throws Exception {
+        server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+        server.end(THREAD1, XID1, XAResource.TMSUSPEND,false);
+
+        try {
+            server.prepare(THREAD1, XID1,false);
+            fail("exception expected"); //$NON-NLS-1$
+        } catch (XATransactionException ex) {
+            assertEquals("Suspended work still exists on transaction Teiid-Xid global:1 branch:null format:0.", ex.getMessage()); //$NON-NLS-1$
+        }
+    }
+    
+    @Test public void testGetTransactionContext() throws Exception {
+        assertSame(server.getOrCreateTransactionContext(THREAD1), server.getOrCreateTransactionContext(THREAD1));
+    }
+    
+    @Test public void testGetTransactions() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+        server.begin(THREAD2);
+        
+        assertEquals(2, server.getTransactions().size());
+        
+        server.commit(THREAD2);
+        assertEquals(1, server.getTransactions().size());
+        
+        Transaction t = server.getTransactions().iterator().next();
+        assertEquals(Long.parseLong(THREAD1), t.getAssociatedSession());
+        assertNotNull(t.getId());
+    }
+    
+    @Test public void testGlobalPrepare() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+        TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+        server.end(THREAD1, XID1, XAResource.TMSUCCESS, false);
+        
+    	server.prepare(THREAD1, XID1, false);
+    	
+    	Mockito.verify(xaTerminator).prepare(tc.getXid());
+    	
+    	server.commit(THREAD1, XID1, true, false);
+    }
+    
+    @Test public void testGlobalPrepareFail() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+        server.end(THREAD1, XID1, XAResource.TMFAIL, false);
+        Mockito.verify(txn).setRollbackOnly();
+    }    
+    
+    @Test public void testGlobalOnePhaseCommit() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	
+        server.end(THREAD1, XID1, XAResource.TMSUCCESS, false);
+        
+        server.prepare(THREAD1, XID1, false);
+
+		
+		server.commit(THREAD1, XID1, true, false);
+		Mockito.verify(xaTerminator).commit(tc.getXid(), false);
+    }  
+    
+    @Test public void testGlobalOnePhaseCommit_force_prepare_through() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	
+        server.end(THREAD1, XID1, XAResource.TMSUCCESS, false);
+        
+		
+		server.commit(THREAD1, XID1, true, false);
+		
+		Mockito.verify(xaTerminator).prepare(tc.getXid());
+		Mockito.verify(xaTerminator).commit(tc.getXid(), false);
+    }  
+    
+    @Test public void testGlobalOnePhaseCommit_force_prepare() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	
+        server.end(THREAD1, XID1, XAResource.TMSUCCESS, false);
+        
+		
+		server.commit(THREAD1, XID1, true, false);
+		
+		// since there are two sources the commit is not single phase
+		Mockito.verify(xaTerminator).prepare(tc.getXid());
+		Mockito.verify(xaTerminator).commit(tc.getXid(), false);
+    }  
+    
+    
+    @Test public void testGlobalOnePhase_teiid_multiple() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	
+        server.end(THREAD1, XID1, XAResource.TMSUCCESS, false);
+        
+        server.prepare(THREAD1, XID1, false);
+
+		
+		server.commit(THREAD1, XID1, true, false);
+		
+		// since there are two sources the commit is not single phase
+		Mockito.verify(xaTerminator).commit(tc.getXid(), false);
+    }    
+    
+    @Test public void testGlobalOnePhaseRoolback() throws Exception {
+    	server.start(THREAD1, XID1, XAResource.TMNOFLAGS, 100,false);
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	
+        server.end(THREAD1, XID1, XAResource.TMSUCCESS, false);
+        
+        server.prepare(THREAD1, XID1, false);
+
+		
+		server.rollback(THREAD1, XID1, false);
+		
+		// since there are two sources the commit is not single phase
+		Mockito.verify(xaTerminator).rollback(tc.getXid());
+    }     
+    
+    @Test public void testRequestCommit() throws Exception{
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	server.begin(tc);
+    	server.commit(tc);
+    	Mockito.verify(tm).commit();
+    }
+    
+    @Test public void testRequestRollback() throws Exception{
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	server.begin(tc);
+    	
+    	server.rollback(tc);
+    	Mockito.verify(tm).rollback();
+    }     
+    
+    @Test public void testLocalCancel() throws Exception {
+        server.begin(THREAD1);
+        
+        server.cancelTransactions(THREAD1, false);
+        
+        Mockito.verify(txn).setRollbackOnly();
+    }  
+    
+    @Test public void testRequestCancel() throws Exception{
+    	TransactionContext tc = server.getOrCreateTransactionContext(THREAD1);
+    	server.begin(tc);
+    	
+    	server.cancelTransactions(THREAD1, true);
+    	Mockito.verify(txn).setRollbackOnly();
+    }      
+}

Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java	2010-07-23 21:44:19 UTC (rev 2371)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java	2010-07-24 03:25:41 UTC (rev 2372)
@@ -65,7 +65,7 @@
 import org.teiid.dqp.internal.process.DQPConfiguration;
 import org.teiid.dqp.internal.process.DQPCore;
 import org.teiid.dqp.internal.process.DQPWorkContext;
-import org.teiid.dqp.internal.transaction.TransactionServerImpl;
+import org.teiid.dqp.internal.process.TransactionServerImpl;
 import org.teiid.dqp.service.BufferService;
 import org.teiid.dqp.service.SessionService;
 import org.teiid.dqp.service.SessionServiceException;



More information about the teiid-commits mailing list