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;