You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2013/07/27 00:01:50 UTC

[01/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Updated Branches:
  refs/heads/master 81b121bbe -> f5e5b39c9


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
deleted file mode 100644
index 40fcbbf..0000000
--- a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Method;
-
-import com.cloud.utils.component.ComponentMethodInterceptor;
-
-public class TransactionContextBuilder implements ComponentMethodInterceptor {
-	public TransactionContextBuilder() {
-	}
-	
-	@Override
-	public boolean needToIntercept(Method method) {
-        DB db = method.getAnnotation(DB.class);
-        if (db != null) {
-            return true;
-        }
-        
-        Class<?> clazz = method.getDeclaringClass();
-        
-        do {
-            db = clazz.getAnnotation(DB.class);
-            if (db != null) {
-                return true;
-            }
-            clazz = clazz.getSuperclass();
-        } while (clazz != Object.class && clazz != null);
-        
-        return false;
-    }
-
-	@Override
-    public Object interceptStart(Method method, Object target) {
-    	return Transaction.open(method.getName());
-    }
-    
-	@Override
-    public void interceptComplete(Method method, Object target, Object objReturnedInInterceptStart) {
-    	Transaction txn = (Transaction)objReturnedInInterceptStart;
-    	if(txn != null)
-    		txn.close();
-    }
-    
-	@Override
-    public void interceptException(Method method, Object target, Object objReturnedInInterceptStart) {
-    	Transaction txn = (Transaction)objReturnedInInterceptStart;
-    	if(txn != null)
-    		txn.close();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/TransactionMBean.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/TransactionMBean.java b/utils/src/com/cloud/utils/db/TransactionMBean.java
deleted file mode 100644
index b868360..0000000
--- a/utils/src/com/cloud/utils/db/TransactionMBean.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.List;
-import java.util.Map;
-
-public interface TransactionMBean {
-    int getTransactionCount();
-    
-    int[] getActiveTransactionCount();
-    
-    List<Map<String, String>> getTransactions();
-    
-    List<Map<String, String>> getActiveTransactions();
-    
-    List<Map<String, String>> getTransactionsWithDatabaseConnection();
-    
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/TransactionMBeanImpl.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/TransactionMBeanImpl.java b/utils/src/com/cloud/utils/db/TransactionMBeanImpl.java
deleted file mode 100644
index d51a9bd..0000000
--- a/utils/src/com/cloud/utils/db/TransactionMBeanImpl.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.sql.Connection;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.management.StandardMBean;
-
-import com.cloud.utils.db.Transaction.StackElement;
-
-public class TransactionMBeanImpl extends StandardMBean implements TransactionMBean {
-    
-    Map<Long, Transaction> _txns = new ConcurrentHashMap<Long, Transaction>();
-    
-    public TransactionMBeanImpl() {
-        super(TransactionMBean.class, false);
-    }
-    
-    public void addTransaction(Transaction txn) {
-        _txns.put(txn.getId(), txn);
-    }
-    
-    public void removeTransaction(Transaction txn) {
-        _txns.remove(txn.getId());
-    }
-    
-    @Override
-    public int getTransactionCount() {
-        return _txns.size();
-    }
-    
-    @Override
-    public int[] getActiveTransactionCount() {
-        int[] count = new int[2];
-        count[0] = 0;
-        count[1] = 0;
-        for (Transaction txn : _txns.values()) {
-            if (txn.getStack().size() > 0) {
-                count[0]++;
-            }
-            if (txn.getCurrentConnection() != null) {
-                count[1]++;
-            }
-        }
-        return count;
-    }
-    
-    @Override
-    public List<Map<String, String>> getTransactions() {
-        ArrayList<Map<String, String>> txns = new ArrayList<Map<String, String>>();
-        for (Transaction info : _txns.values()) {
-            txns.add(toMap(info));
-        }
-        return txns;
-    }
-    
-    @Override
-    public List<Map<String, String>> getActiveTransactions() {
-        ArrayList<Map<String, String>> txns = new ArrayList<Map<String, String>>();
-        for (Transaction txn : _txns.values()) {
-            if (txn.getStack().size() > 0 || txn.getCurrentConnection() != null) {
-                txns.add(toMap(txn));
-            }
-        }
-        return txns;
-    }
-    
-    protected Map<String, String> toMap(Transaction txn) {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("name", txn.getName());
-        map.put("id", Long.toString(txn.getId()));
-        map.put("creator", txn.getCreator());
-        Connection conn = txn.getCurrentConnection();
-        map.put("db", conn != null ? Integer.toString(System.identityHashCode(conn)) : "none");
-        StringBuilder buff = new StringBuilder();
-        for (StackElement element : txn.getStack()) {
-            buff.append(element.toString()).append(",");
-        }
-        map.put("stack", buff.toString());
-        
-        return map;
-    }
-
-    @Override
-    public List<Map<String, String>> getTransactionsWithDatabaseConnection() {
-        ArrayList<Map<String, String>> txns = new ArrayList<Map<String, String>>();
-        for (Transaction txn : _txns.values()) {
-            if (txn.getCurrentConnection() != null) {
-                txns.add(toMap(txn));
-            }
-        }
-        return txns;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/UpdateBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/UpdateBuilder.java b/utils/src/com/cloud/utils/db/UpdateBuilder.java
deleted file mode 100755
index c13aa51..0000000
--- a/utils/src/com/cloud/utils/db/UpdateBuilder.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-
-import com.cloud.utils.Ternary;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class UpdateBuilder implements MethodInterceptor {
-    protected Map<String, Ternary<Attribute, Boolean, Object>> _changes;
-    protected HashMap<Attribute, Object> _collectionChanges;
-    protected GenericDaoBase<?, ?> _dao;
-    
-    protected UpdateBuilder(GenericDaoBase<?, ?> dao) {
-        _dao = dao;
-        _changes = new HashMap<String, Ternary<Attribute, Boolean, Object>>();
-    }
-    
-    @Override
-    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
-        String name = method.getName();
-        if (name.startsWith("set")) {
-        	String field = methodToField(name, 3);
-            makeChange(field, args[0]);
-        } else if (name.startsWith("incr")) {
-        	makeIncrChange(name, args);
-        } else if (name.startsWith("decr")) {
-        	makeDecrChange(name, args);
-        }
-        return methodProxy.invokeSuper(object, args);
-    }
-    
-    private final String methodToField(String method, int start) {
-    	char[] chs = method.toCharArray();
-    	chs[start] = Character.toLowerCase(chs[start]);
-    	return new String(chs, start, chs.length - start);
-    }
-    
-    protected Attribute makeChange(String field, Object value) {
-        Attribute attr = _dao._allAttributes.get(field);
-        
-        assert (attr == null || attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field;
-        if (attr != null) {
-            if (attr.attache == null) {
-                _changes.put(field, new Ternary<Attribute, Boolean, Object>(attr, null, value));
-            } else {
-                if (_collectionChanges == null) {
-                    _collectionChanges = new HashMap<Attribute, Object>();
-                }
-                _collectionChanges.put(attr, value);
-            }
-        }
-        return attr;
-    }
-    
-    protected void makeIncrChange(String method, Object[] args) {
-    	String field = methodToField(method, 4);
-    	Attribute attr = _dao._allAttributes.get(field);
-        assert (attr != null && attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field;
-    	incr(attr, args == null || args.length == 0 ? 1 : args[0]);
-    }
-    
-    protected void makeDecrChange(String method, Object[] args) {
-    	String field = methodToField(method, 4);
-    	Attribute attr = _dao._allAttributes.get(field);
-        assert (attr != null && attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field;
-    	decr(attr, args == null || args.length == 0 ? 1 : args[0]);
-    }
-    
-    public void set(Object entity, String name, Object value) {
-    	Attribute attr = makeChange(name, value);
-
-    	set(entity, attr, value);
-    }
-    
-    public void set(Object entity, Attribute attr, Object value) {
-        _changes.put(attr.field.getName(), new Ternary<Attribute, Boolean, Object>(attr, null, value));
-        try {
-			attr.field.set(entity, value);
-		} catch (IllegalArgumentException e) {
-			throw new CloudRuntimeException("Unable to update " + attr.field.getName() + " with " + value, e);
-		} catch (IllegalAccessException e) {
-			throw new CloudRuntimeException("Unable to update " + attr.field.getName() + " with " + value, e);
-		}
-    }
-    
-    public void incr(Attribute attr, Object value) {
-        _changes.put(attr.field.getName(), new Ternary<Attribute, Boolean, Object>(attr, true, value));
-    }
-    
-    public void decr(Attribute attr, Object value) {
-        _changes.put(attr.field.getName(), new Ternary<Attribute, Boolean, Object>(attr, false, value));
-    }
-    
-    public boolean hasChanges() {
-        return (_changes.size() + (_collectionChanges != null ? _collectionChanges.size() : 0)) != 0;
-    }
-    
-    public boolean has(String name) {
-        return _changes.containsKey(name);
-    }
-    
-    public Map<Attribute, Object> getCollectionChanges() {
-        return _collectionChanges;
-    }
-    
-    public void clear() {
-        _changes.clear();
-        if (_collectionChanges != null) {
-            _collectionChanges.clear();
-            _collectionChanges = null;
-        }
-    }
-    
-    public StringBuilder toSql(String tables) {
-    	if (_changes.isEmpty()) {
-    		return null;
-    	}
-    	
-    	return SqlGenerator.buildMysqlUpdateSql(tables, _changes.values());
-    }
-    
-    public Collection<Ternary<Attribute, Boolean, Object>> getChanges() {
-    	return _changes.values();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/UpdateFilter.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/UpdateFilter.java b/utils/src/com/cloud/utils/db/UpdateFilter.java
deleted file mode 100644
index 37b35b1..0000000
--- a/utils/src/com/cloud/utils/db/UpdateFilter.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Method;
-
-import net.sf.cglib.proxy.CallbackFilter;
-
-public class UpdateFilter implements CallbackFilter {
-    @Override
-    public int accept(Method method) {
-        String name = method.getName();
-        return (name.startsWith("set") || name.startsWith("incr") || name.startsWith("decr")) ? 1 : 0;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/DbAnnotatedBase.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/DbAnnotatedBase.java b/utils/test/com/cloud/utils/db/DbAnnotatedBase.java
deleted file mode 100644
index f87b20f..0000000
--- a/utils/test/com/cloud/utils/db/DbAnnotatedBase.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-
-import junit.framework.Assert;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-@Component
-@DB
-public class DbAnnotatedBase {
-    private static final Logger s_logger = Logger.getLogger(DbAnnotatedBase.class);
-
-    @Inject DummyComponent _dummy;
-    
-    @PostConstruct
-    public void initTest() {
-    	Assert.assertTrue(true);
-    }
-    
-    public void MethodWithClassDbAnnotated() {
-    	s_logger.info("called");
-    	_dummy.sayHello();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java b/utils/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java
deleted file mode 100644
index 38e045c..0000000
--- a/utils/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class DbAnnotatedBaseDerived extends DbAnnotatedBase {
-
-	@DB
-	public void DbAnnotatedMethod() {
-	}
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/DbTestDao.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/DbTestDao.java b/utils/test/com/cloud/utils/db/DbTestDao.java
deleted file mode 100644
index 9530b3b..0000000
--- a/utils/test/com/cloud/utils/db/DbTestDao.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.sql.PreparedStatement;
-import java.util.Date;
-import java.util.TimeZone;
-
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class DbTestDao extends GenericDaoBase<DbTestVO, Long> implements GenericDao<DbTestVO, Long> {
-    protected DbTestDao() {
-    }
-
-    @DB
-    public void create(int fldInt, long fldLong, String fldString) {
-        Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-            pstmt = txn
-                    .prepareAutoCloseStatement("insert into cloud.test(fld_int, fld_long, fld_string) values(?, ?, ?)");
-            pstmt.setInt(1, fldInt);
-            pstmt.setLong(2, fldLong);
-            pstmt.setString(3, fldString);
-
-            pstmt.executeUpdate();
-            txn.commit();
-        } catch (Exception e) {
-            throw new CloudRuntimeException("Problem with creating a record in test table", e);
-        }
-    }
-
-    @DB
-    public void update(int fldInt, long fldLong, String fldString) {
-        Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement("update cloud.test set fld_int=?, fld_long=? where fld_string=?");
-            pstmt.setInt(1, fldInt);
-            pstmt.setLong(2, fldLong);
-            pstmt.setString(3, fldString);
-
-            pstmt.executeUpdate();
-            txn.commit();
-        } catch (Exception e) {
-            throw new CloudRuntimeException("Problem with creating a record in test table", e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/DbTestUtils.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/DbTestUtils.java b/utils/test/com/cloud/utils/db/DbTestUtils.java
deleted file mode 100644
index 11ae1aa..0000000
--- a/utils/test/com/cloud/utils/db/DbTestUtils.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import com.cloud.utils.PropertiesUtil;
-
-public class DbTestUtils {
-    
-    public static void executeScript(String file, boolean autoCommit, boolean stopOnError) {
-        File cleanScript = PropertiesUtil.findConfigFile(file);
-        if (cleanScript == null) {
-            throw new RuntimeException("Unable to clean the database because I can't find " + file);
-        }
-        
-        Connection conn = Transaction.getStandaloneConnection();
-        
-        ScriptRunner runner = new ScriptRunner(conn, autoCommit, stopOnError);
-        FileReader reader;
-        try {
-            reader = new FileReader(cleanScript);
-        } catch (FileNotFoundException e) {
-            throw new RuntimeException("Unable to read " + file, e);
-        } 
-        try {
-            runner.runScript(reader);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to read " + file, e);
-        } catch (SQLException e) {
-            throw new RuntimeException("Unable to execute " + file, e);
-        }
-        
-        try {
-            conn.close();
-        } catch (SQLException e) {
-            throw new RuntimeException("Unable to close DB connection", e);
-        }
-    }
-
-    public static void executeUsageScript(String file, boolean autoCommit, boolean stopOnError) {
-        File cleanScript = PropertiesUtil.findConfigFile(file);
-        if (cleanScript == null) {
-            throw new RuntimeException("Unable to clean the database because I can't find " + file);
-        }
-        
-        Connection conn = Transaction.getStandaloneUsageConnection();
-        
-        ScriptRunner runner = new ScriptRunner(conn, autoCommit, stopOnError);
-        FileReader reader;
-        try {
-            reader = new FileReader(cleanScript);
-        } catch (FileNotFoundException e) {
-            throw new RuntimeException("Unable to read " + file, e);
-        } 
-        try {
-            runner.runScript(reader);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to read " + file, e);
-        } catch (SQLException e) {
-            throw new RuntimeException("Unable to execute " + file, e);
-        }
-        
-        try {
-            conn.close();
-        } catch (SQLException e) {
-            throw new RuntimeException("Unable to close DB connection", e);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/DbTestVO.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/DbTestVO.java b/utils/test/com/cloud/utils/db/DbTestVO.java
deleted file mode 100644
index 5285bfe..0000000
--- a/utils/test/com/cloud/utils/db/DbTestVO.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "test")
-public class DbTestVO {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    long id;
-
-    @Column(name = "fld_int")
-    int fieldInt;
-
-    @Column(name = "fld_long")
-    Long fieldLong;
-
-    @Column(name = "fld_string")
-    String fieldString;
-
-    public String getFieldString() {
-        return fieldString;
-    }
-
-    public int getFieldInt() {
-        return fieldInt;
-    }
-
-    public long getFieldLong() {
-        return fieldLong;
-    }
-
-    public DbTestVO() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/DummyComponent.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/DummyComponent.java b/utils/test/com/cloud/utils/db/DummyComponent.java
deleted file mode 100644
index 2922630..0000000
--- a/utils/test/com/cloud/utils/db/DummyComponent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class DummyComponent {
-
-	public void sayHello() {
-		System.out.println("Hello, world");
-	}
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/ElementCollectionTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/ElementCollectionTest.java b/utils/test/com/cloud/utils/db/ElementCollectionTest.java
deleted file mode 100644
index b860af5..0000000
--- a/utils/test/com/cloud/utils/db/ElementCollectionTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-import org.apache.log4j.Logger;
-
-
-public class ElementCollectionTest extends TestCase {
-    static final Logger s_logger = Logger.getLogger(ElementCollectionTest.class);
-    ArrayList<String> ar = null;
-    List<String> lst = null;
-    Collection<String> coll = null;
-    String[] array = null;
-
-    public void testArrayList() throws Exception {
-        Field[] fields = this.getClass().getDeclaredFields();
-        for (Field field : fields) {
-            if (Modifier.isStatic(field.getModifiers())) {
-                continue;
-            }
-            Class<?> type1 = field.getType();
-            Object collection = null;
-            if (!type1.isArray()) {
-                ParameterizedType type = (ParameterizedType)field.getGenericType();
-                Type rawType = type.getRawType();
-                Class<?> rawClazz = (Class<?>)rawType;
-                if (!Modifier.isAbstract(rawClazz.getModifiers()) && !rawClazz.isInterface() && rawClazz.getConstructors().length != 0 && rawClazz.getConstructor() != null) {
-                    collection = rawClazz.newInstance();
-                }
-
-                if (collection == null) {
-                    if (Collection.class.isAssignableFrom(rawClazz)) {
-                        collection = new ArrayList();
-                    } else if (Set.class.isAssignableFrom(rawClazz)) {
-                        collection = new HashSet();
-                    }
-                }
-            } else {
-                collection = Array.newInstance(String.class, 1);
-            }
-            field.set(this, collection);
-            assert (field.get(this) != null);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/GlobalLockTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/GlobalLockTest.java b/utils/test/com/cloud/utils/db/GlobalLockTest.java
deleted file mode 100644
index 01e1e33..0000000
--- a/utils/test/com/cloud/utils/db/GlobalLockTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import org.apache.log4j.Logger;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import junit.framework.Assert;
-
-import com.cloud.utils.Profiler;
-import com.cloud.utils.testcase.Log4jEnabledTestCase;
-
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations="classpath:/testContext.xml")
-public class GlobalLockTest {
-    public static final Logger s_logger = Logger.getLogger(GlobalLockTest.class);
-    private final static GlobalLock _workLock = GlobalLock.getInternLock("SecurityGroupWork");
-    public static class Worker implements Runnable {
-        int id = 0;
-        int timeoutSeconds = 10;
-        int jobDuration = 2;
-        public Worker(int id, int timeout, int duration) {
-            this.id = id;
-            timeoutSeconds = timeout;
-            jobDuration = duration;
-        }
-        public void run() {
-            boolean locked = false;
-            try {
-                Profiler p = new Profiler();
-                p.start();
-                locked = _workLock.lock(timeoutSeconds);
-                p.stop();
-                System.out.println("Thread " + id + " waited " + p.getDuration() + " ms, locked=" + locked);
-                if (locked) {
-                    Thread.sleep(jobDuration*1000);
-                }
-            } catch (InterruptedException e) {
-            } finally {
-                if (locked) {
-                    boolean unlocked = _workLock.unlock();
-                    System.out.println("Thread " + id + "  unlocked=" + unlocked);
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testTimeout() {
-        Thread [] pool = new Thread[50];
-        for (int i=0; i < pool.length; i++) {
-            pool[i] = new Thread(new Worker(i, 5, 3));
-        }
-        for (int i=0; i < pool.length; i++) {
-            pool[i].start();
-        }
-        for (int i=0; i < pool.length; i++) {
-            try {
-                pool[i].join();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/Merovingian2Test.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/Merovingian2Test.java b/utils/test/com/cloud/utils/db/Merovingian2Test.java
deleted file mode 100644
index 8246faa..0000000
--- a/utils/test/com/cloud/utils/db/Merovingian2Test.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.log4j.Logger;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class Merovingian2Test extends TestCase {
-    static final Logger s_logger = Logger.getLogger(Merovingian2Test.class);
-    Merovingian2 _lockMaster = Merovingian2.createLockMaster(1234);
-    
-    @Override @Before
-    protected void setUp() throws Exception {
-        _lockMaster.cleanupThisServer();
-    }
-    
-    @Override @After
-    protected void tearDown() throws Exception {
-        _lockMaster.cleanupThisServer();
-    }
-
-    @Test
-    public void testLockAndRelease() {
-        
-        s_logger.info("Testing first acquire");
-        boolean result = _lockMaster.acquire("first"+1234, 5);
-        Assert.assertTrue(result);
-        
-        s_logger.info("Testing acquire of different lock");
-        result = _lockMaster.acquire("second"+1234, 5);
-        Assert.assertTrue(result);
-        
-        s_logger.info("Testing reacquire of the same lock");
-        result = _lockMaster.acquire("first"+1234, 5);
-        Assert.assertTrue(result);
-        
-        int count = _lockMaster.owns("first"+1234);
-        Assert.assertEquals(count, 2);
-        
-        count = _lockMaster.owns("second"+1234);
-        Assert.assertEquals(count, 1);
-        
-        s_logger.info("Testing release of the first lock");
-        result = _lockMaster.release("first"+1234);
-        Assert.assertTrue(result);
-        
-        count = _lockMaster.owns("first"+1234);
-        Assert.assertEquals(count, 1);
-        
-        s_logger.info("Testing release of the second lock");
-        result = _lockMaster.release("second"+1234);
-        Assert.assertTrue(result);
-        
-        result = _lockMaster.release("first"+1234);
-        Assert.assertTrue(result);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/TransactionContextBuilderTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/TransactionContextBuilderTest.java b/utils/test/com/cloud/utils/db/TransactionContextBuilderTest.java
deleted file mode 100644
index 33e7aa0..0000000
--- a/utils/test/com/cloud/utils/db/TransactionContextBuilderTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import com.cloud.utils.component.ComponentContext;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations="classpath:/com/cloud/utils/db/transactioncontextBuilderTest.xml")
-public class TransactionContextBuilderTest {
-
-	@Inject
-	DbAnnotatedBaseDerived _derived; 
-	
-	DbAnnotatedBase _base;
-	
-	@Inject
-	List<DbAnnotatedBase> _list;
-	
-	@Test
-	public void test() {
-		// _derived.DbAnnotatedMethod();
-		// _base.MethodWithClassDbAnnotated();
-		
-		// test @DB injection on dynamically constructed objects
-		DbAnnotatedBase base = ComponentContext.inject(new DbAnnotatedBase());
-		base.MethodWithClassDbAnnotated();
-
-/*		
-		Map<String, DbAnnotatedBase> components = ComponentContext.getApplicationContext().getBeansOfType(DbAnnotatedBase.class);
-		for(Map.Entry<String, DbAnnotatedBase> entry : components.entrySet()) {
-			System.out.println(entry.getKey());
-			entry.getValue().MethodWithClassDbAnnotated();
-		}
-*/
-		for(DbAnnotatedBase entry : _list) {
-			entry.MethodWithClassDbAnnotated();
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/db/TransactionTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/db/TransactionTest.java b/utils/test/com/cloud/utils/db/TransactionTest.java
deleted file mode 100644
index 101a533..0000000
--- a/utils/test/com/cloud/utils/db/TransactionTest.java
+++ /dev/null
@@ -1,214 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- * A test fixture to test APIs or bugs found for Transaction class. This test fixture will do one time setup before
- * all its testcases to set up a test db table, and then tear down these test db artifacts after all testcases are run.
- *
- */
-public class TransactionTest {
-
-    @BeforeClass
-    public static void oneTimeSetup() {
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-        try {
-            conn = Transaction.getStandaloneConnection();
-
-            pstmt = conn.prepareStatement("CREATE TABLE `cloud`.`test` ("
-                    + "`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT," + "`fld_int` int unsigned,"
-                    + "`fld_long` bigint unsigned," + "`fld_string` varchar(255)," + "PRIMARY KEY (`id`)"
-                    + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
-
-            pstmt.execute();
-
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Problem with sql", e);
-        } finally {
-            if (pstmt != null) {
-                try {
-                    pstmt.close();
-                } catch (SQLException e) {
-                }
-            }
-            if (conn != null) {
-                try {
-                    conn.close();
-                } catch (SQLException e) {
-                }
-            }
-        }
-    }
-
-    @Test
-    /**
-     * When a transaction is set to use user-managed db connection, for each following db statement, we should see
-     * that the same db connection is reused rather than acquiring a new one each time in typical transaction model.
-     */
-    public void testUserManagedConnection() {
-        DbTestDao testDao = ComponentContext.inject(DbTestDao.class);
-        Transaction txn = Transaction.open("SingleConnectionThread");
-        Connection conn = null;
-        try {
-            conn = Transaction.getStandaloneConnectionWithException();
-            txn.transitToUserManagedConnection(conn);
-            // try two SQLs to make sure that they are using the same connection
-            // acquired above.
-            testDao.create(1, 1, "Record 1");
-            Connection checkConn = Transaction.currentTxn().getConnection();
-            if (checkConn != conn) {
-                Assert.fail("A new db connection is acquired instead of using old one after create sql");
-            }
-            testDao.update(2, 2, "Record 1");
-            Connection checkConn2 = Transaction.currentTxn().getConnection();
-            if (checkConn2 != conn) {
-                Assert.fail("A new db connection is acquired instead of using old one after update sql");
-            }
-        } catch (SQLException e) {
-            Assert.fail(e.getMessage());
-        } finally {
-            txn.transitToAutoManagedConnection(Transaction.CLOUD_DB);
-            txn.close();
-
-            if (conn != null) {
-                try {
-                    conn.close();
-                } catch (SQLException e) {
-                    throw new CloudRuntimeException("Problem with close db connection", e);
-                }
-            }
-        }
-    }
-
-    @Test
-    /**
-     * This test is simulating ClusterHeartBeat process, where the same transaction and db connection is reused.
-     */
-    public void testTransactionReuse() {
-        DbTestDao testDao = ComponentContext.inject(DbTestDao.class);
-        // acquire a db connection and keep it
-        Connection conn = null;
-        try {
-            conn = Transaction.getStandaloneConnectionWithException();
-        } catch (SQLException ex) {
-            throw new CloudRuntimeException("Problem with getting db connection", ex);
-        }
-
-        // start heartbeat loop, make sure that each loop still use the same
-        // connection
-        Transaction txn = null;
-        for (int i = 0; i < 3; i++) {
-            txn = Transaction.open("HeartbeatSimulator");
-            try {
-
-                txn.transitToUserManagedConnection(conn);
-                testDao.create(i, i, "Record " + i);
-                Connection checkConn = Transaction.currentTxn().getConnection();
-                if (checkConn != conn) {
-                    Assert.fail("A new db connection is acquired instead of using old one in loop " + i);
-                }
-            } catch (SQLException e) {
-                Assert.fail(e.getMessage());
-            } finally {
-                txn.transitToAutoManagedConnection(Transaction.CLOUD_DB);
-                txn.close();
-            }
-        }
-        // close the connection once we are done since we are managing db
-        // connection ourselves.
-        if (conn != null) {
-            try {
-                conn.close();
-            } catch (SQLException e) {
-                throw new CloudRuntimeException("Problem with close db connection", e);
-            }
-        }
-    }
-
-    @After
-    /**
-     * Delete all records after each test, but table is still kept
-     */
-    public void tearDown() {
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-        try {
-            conn = Transaction.getStandaloneConnection();
-
-            pstmt = conn.prepareStatement("truncate table `cloud`.`test`");
-            pstmt.execute();
-
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Problem with sql", e);
-        } finally {
-            if (pstmt != null) {
-                try {
-                    pstmt.close();
-                } catch (SQLException e) {
-                }
-            }
-            if (conn != null) {
-                try {
-                    conn.close();
-                } catch (SQLException e) {
-                }
-            }
-        }
-    }
-
-    @AfterClass
-    public static void oneTimeTearDown() {
-        Connection conn = null;
-        PreparedStatement pstmt = null;
-        try {
-            conn = Transaction.getStandaloneConnection();
-
-            pstmt = conn.prepareStatement("DROP TABLE IF EXISTS `cloud`.`test`");
-            pstmt.execute();
-
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Problem with sql", e);
-        } finally {
-            if (pstmt != null) {
-                try {
-                    pstmt.close();
-                } catch (SQLException e) {
-                }
-            }
-            if (conn != null) {
-                try {
-                    conn.close();
-                } catch (SQLException e) {
-                }
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java b/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java
deleted file mode 100644
index 5e3571a..0000000
--- a/utils/test/com/cloud/utils/log/CglibThrowableRendererTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.log;
-
-import junit.framework.TestCase;
-
-import org.apache.log4j.*;
-
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import org.apache.log4j.spi.RootLogger;
-import org.apache.log4j.spi.ThrowableRenderer;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import java.io.CharArrayWriter;
-import java.io.Writer;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations="classpath:/testContext.xml")
-public class CglibThrowableRendererTest extends TestCase {
-    static Logger another = Logger.getLogger("TEST");
-
-    private final static Logger s_logger = Logger.getLogger(CglibThrowableRendererTest.class);
-    public static class TestClass {
-    	
-    	public TestClass() {
-    	}
-    	
-        @DB
-        public void exception1() {
-            throw new IllegalArgumentException("What a bad exception");
-        }
-        public void exception2() {
-            try {
-                exception1();
-            } catch (Exception e) {
-                throw new CloudRuntimeException("exception2", e);
-            }
-        }
-        @DB
-        public void exception() {
-            try {
-                exception2();
-            } catch (Exception e) {
-                throw new CloudRuntimeException("exception", e);
-            }
-        }
-    }
-
-    private Logger getAlternateLogger(Writer writer, ThrowableRenderer renderer) {
-        Hierarchy hierarchy = new Hierarchy(new RootLogger(Level.INFO));
-        if (renderer != null) {
-            hierarchy.setThrowableRenderer(renderer);
-        }
-        Logger alternateRoot = hierarchy.getRootLogger();
-        alternateRoot.addAppender(new WriterAppender(new SimpleLayout(), writer));
-        return alternateRoot;
-    }
-
-    @Test
-    public void testException() {
-        Writer w = new CharArrayWriter();
-        Logger alt = getAlternateLogger(w, null);
-
-        TestClass test = new TestClass();
-        try {
-            test.exception();
-        } catch (Exception e) {
-            alt.warn("exception caught", e);
-        }
-        // first check that we actually have some call traces containing "<generated>"
-       // assertTrue(w.toString().contains("<generated>"));
-
-        w = new CharArrayWriter();
-        alt = getAlternateLogger(w, new CglibThrowableRenderer());
-
-        try {
-            test.exception();
-        } catch (Exception e) {
-            alt.warn("exception caught", e);
-        }
-        // then we check that CglibThrowableRenderer indeed remove those occurrences
-        assertFalse(w.toString().contains("<generated>"));
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/test/org/apache/cloudstack/test/utils/SpringUtils.java
----------------------------------------------------------------------
diff --git a/utils/test/org/apache/cloudstack/test/utils/SpringUtils.java b/utils/test/org/apache/cloudstack/test/utils/SpringUtils.java
deleted file mode 100644
index 220bd80..0000000
--- a/utils/test/org/apache/cloudstack/test/utils/SpringUtils.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.test.utils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.component.ComponentInstantiationPostProcessor;
-import com.cloud.utils.component.ComponentMethodInterceptor;
-import com.cloud.utils.db.TransactionContextBuilder;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class SpringUtils {
-
-    /**
-     * This method allows you to use @ComponentScan for your unit testing but
-     * it limits the scope of the classes found to the class specified in
-     * the @ComponentScan annotation.
-     *
-     * Without using this method, the default behavior of @ComponentScan is
-     * to actually scan in the package of the class specified rather than
-     * only the class. This can cause extra classes to be loaded which causes
-     * the classes these extra classes depend on to be loaded. The end effect
-     * is often most of the project gets loaded.
-     *
-     * In order to use this method properly, you must do the following: <li>
-     *   - Specify @ComponentScan with basePackageClasses, includeFilters, and
-     *     useDefaultFilters=true.  See the following example.
-     *
-     * <pre>
-     *     @ComponentScan(basePackageClasses={AffinityGroupServiceImpl.class, EventUtils.class},
-     *     includeFilters={@Filter(value=TestConfiguration.Library.class, type=FilterType.CUSTOM)},
-     *     useDefaultFilters=false)
-     * </pre>
-     *
-     *   - Create a Library class and use that to call this method.  See the
-     *     following example.  The Library class you define here is the Library
-     *     class being added in the filter above.
-     *
-     * <pre>
-     * public static class Library implements TypeFilter {
-     *      @Override
-     *      public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
-     *          ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
-     *          return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-     *      }
-     * }
-     * </pre>
-     *
-     * @param clazzName name of the class that should be included in the Spring components
-     * @param cs ComponentScan annotation that was declared on the configuration
-     *
-     * @return
-     */
-    public static boolean includedInBasePackageClasses(String clazzName, ComponentScan cs) {
-        Class<?> clazzToCheck;
-        try {
-            clazzToCheck = Class.forName(clazzName);
-        } catch (ClassNotFoundException e) {
-            throw new CloudRuntimeException("Unable to find " + clazzName);
-        }
-        Class<?>[] clazzes = cs.basePackageClasses();
-        for (Class<?> clazz : clazzes) {
-            if (clazzToCheck.isAssignableFrom(clazz)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public static class CloudStackTestConfiguration {
-
-        @Bean
-        public ComponentContext componentContext() {
-            return new ComponentContext();
-        }
-
-        @Bean
-        public TransactionContextBuilder transactionContextBuilder() {
-            return new TransactionContextBuilder();
-        }
-
-        @Bean
-        public ComponentInstantiationPostProcessor instantiatePostProcessor() {
-            ComponentInstantiationPostProcessor processor = new ComponentInstantiationPostProcessor();
-
-            List<ComponentMethodInterceptor> interceptors = new ArrayList<ComponentMethodInterceptor>();
-            interceptors.add(new TransactionContextBuilder());
-            processor.setInterceptors(interceptors);
-
-            return processor;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/vmware-base/pom.xml
----------------------------------------------------------------------
diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml
index c5d555e..90e0709 100644
--- a/vmware-base/pom.xml
+++ b/vmware-base/pom.xml
@@ -33,6 +33,11 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-db</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloud-api</artifactId>
         <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
index dd0f889..c92b855 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
@@ -27,21 +27,6 @@ import java.util.Map;
 
 import org.apache.log4j.Logger;
 
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.utils.ActionDelegate;
-import com.cloud.utils.Pair;
-import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
-import com.cloud.utils.cisco.n1kv.vsm.PolicyMap;
-import com.cloud.utils.cisco.n1kv.vsm.PortProfile;
-import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.BindingType;
-import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.OperationType;
-import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.PortProfileType;
-import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.SwitchPortMode;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
 import com.vmware.vim25.AlreadyExistsFaultMsg;
 import com.vmware.vim25.BoolPolicy;
 import com.vmware.vim25.DVPortSetting;
@@ -79,6 +64,22 @@ import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec;
 
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.utils.ActionDelegate;
+import com.cloud.utils.Pair;
+import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
+import com.cloud.utils.cisco.n1kv.vsm.PolicyMap;
+import com.cloud.utils.cisco.n1kv.vsm.PortProfile;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.BindingType;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.OperationType;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.PortProfileType;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.SwitchPortMode;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
 public class HypervisorHostHelper {
     private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class);
     private static final int DEFAULT_LOCK_TIMEOUT_SECONDS = 600;
@@ -446,29 +447,29 @@ public class HypervisorHostHelper {
         Integer vid = null;
         Integer spvlanid = null;  // secondary pvlan id
 
-        /** This is the list of BroadcastDomainTypes we can actually 
+        /** This is the list of BroadcastDomainTypes we can actually
          * prepare networks for in this function.
          */
-        BroadcastDomainType[] supportedBroadcastTypes = 
-                new BroadcastDomainType[] { BroadcastDomainType.Lswitch, 
-                BroadcastDomainType.LinkLocal, 
-                BroadcastDomainType.Native, 
+        BroadcastDomainType[] supportedBroadcastTypes =
+                new BroadcastDomainType[] { BroadcastDomainType.Lswitch,
+                BroadcastDomainType.LinkLocal,
+                BroadcastDomainType.Native,
                 BroadcastDomainType.Pvlan,
                 BroadcastDomainType.Storage,
                 BroadcastDomainType.UnDecided,
                 BroadcastDomainType.Vlan };
 
         if (!Arrays.asList(supportedBroadcastTypes).contains(broadcastDomainType)) {
-            throw new InvalidParameterException("BroadcastDomainType " + broadcastDomainType + 
+            throw new InvalidParameterException("BroadcastDomainType " + broadcastDomainType +
                     " it not supported on a VMWare hypervisor at this time.");
         }
 
         if (broadcastDomainType == BroadcastDomainType.Lswitch) {
             if (vSwitchType == VirtualSwitchType.NexusDistributedVirtualSwitch) {
-                throw new InvalidParameterException("Nexus Distributed Virtualswitch is not supported with BroadcastDomainType " + 
+                throw new InvalidParameterException("Nexus Distributed Virtualswitch is not supported with BroadcastDomainType " +
                         broadcastDomainType);
             }
-            /** 
+            /**
              * Nicira NVP requires all vms to be connected to a single port-group.
              * A unique vlan needs to be set per port. This vlan is specific to
              * this implementation and has no reference to other vlans in CS
@@ -552,7 +553,7 @@ public class HypervisorHostHelper {
             }
             long averageBandwidth = 0L;
             if (networkRateMbps != null && networkRateMbps.intValue() > 0) {
-                averageBandwidth = (long) (networkRateMbps.intValue() * 1024L * 1024L);
+                averageBandwidth = networkRateMbps.intValue() * 1024L * 1024L;
             }
             // We chose 50% higher allocation than average bandwidth.
             // TODO(sateesh): Optionally let user specify the peak coefficient
@@ -601,7 +602,7 @@ public class HypervisorHostHelper {
         return vCenterApiVersion.compareTo(minVcenterApiVersionForFeature) >= 0 ? true : false;
     }
 
-    private static void setupPVlanPair(DistributedVirtualSwitchMO dvSwitchMo, ManagedObjectReference morDvSwitch, 
+    private static void setupPVlanPair(DistributedVirtualSwitchMO dvSwitchMo, ManagedObjectReference morDvSwitch,
             Integer vid, Integer spvlanid) throws Exception {
         Map<Integer, HypervisorHostHelper.PvlanType> vlanmap = dvSwitchMo.retrieveVlanPvlan(vid, spvlanid, morDvSwitch);
         if (!vlanmap.isEmpty()) {
@@ -664,7 +665,7 @@ public class HypervisorHostHelper {
 
     }
 
-    private static void createPortGroup(String physicalNetwork, String networkName, Integer vid, Integer spvlanid, DatacenterMO dataCenterMo, 
+    private static void createPortGroup(String physicalNetwork, String networkName, Integer vid, Integer spvlanid, DatacenterMO dataCenterMo,
             DVSTrafficShapingPolicy shapingPolicy, DVSSecurityPolicy secPolicy, DistributedVirtualSwitchMO dvSwitchMo, int numPorts, boolean autoExpandSupported) throws Exception{
         VmwareDistributedVirtualSwitchVlanSpec vlanSpec = null;
         VmwareDistributedVirtualSwitchPvlanSpec pvlanSpec = null;
@@ -717,7 +718,7 @@ public class HypervisorHostHelper {
                     throw new Exception(msg);
                 }
             }
-        }        
+        }
     }
     
      public static ManagedObjectReference waitForDvPortGroupReady(
@@ -806,12 +807,12 @@ public class HypervisorHostHelper {
         LongPolicy burstSize = new LongPolicy();
 
         isEnabled.setValue(true);
-        averageBandwidth.setValue((long) networkRateMbps.intValue() * 1024L * 1024L);
+        averageBandwidth.setValue(networkRateMbps.intValue() * 1024L * 1024L);
         // We chose 50% higher allocation than average bandwidth.
         // TODO(sateesh): Also let user specify the peak coefficient
         peakBandwidth.setValue((long) (averageBandwidth.getValue() * 1.5));
         // TODO(sateesh): Also let user specify the burst coefficient
-        burstSize.setValue((long) (5 * averageBandwidth.getValue() / 8));
+        burstSize.setValue(5 * averageBandwidth.getValue() / 8);
 
         shapingPolicy.setEnabled(isEnabled);
         shapingPolicy.setAverageBandwidth(averageBandwidth);
@@ -889,25 +890,25 @@ public class HypervisorHostHelper {
         String networkName;
         Integer vid = null;
 
-        /** This is the list of BroadcastDomainTypes we can actually 
+        /** This is the list of BroadcastDomainTypes we can actually
          * prepare networks for in this function.
          */
-        BroadcastDomainType[] supportedBroadcastTypes = 
-                new BroadcastDomainType[] { BroadcastDomainType.Lswitch, 
-                BroadcastDomainType.LinkLocal, 
-                BroadcastDomainType.Native, 
+        BroadcastDomainType[] supportedBroadcastTypes =
+                new BroadcastDomainType[] { BroadcastDomainType.Lswitch,
+                BroadcastDomainType.LinkLocal,
+                BroadcastDomainType.Native,
                 BroadcastDomainType.Pvlan,
                 BroadcastDomainType.Storage,
                 BroadcastDomainType.UnDecided,
                 BroadcastDomainType.Vlan };
 
         if (!Arrays.asList(supportedBroadcastTypes).contains(broadcastDomainType)) {
-            throw new InvalidParameterException("BroadcastDomainType " + broadcastDomainType + 
+            throw new InvalidParameterException("BroadcastDomainType " + broadcastDomainType +
                     " it not supported on a VMWare hypervisor at this time.");
         }
 
         if (broadcastDomainType == BroadcastDomainType.Lswitch) {
-            /** 
+            /**
              * Nicira NVP requires each vm to have its own port-group with a dedicated
              * vlan. We'll set the name of the pg to the uuid of the nic.
              */
@@ -934,7 +935,7 @@ public class HypervisorHostHelper {
         if(networkRateMbps != null && networkRateMbps.intValue() > 0) {
             shapingPolicy = new HostNetworkTrafficShapingPolicy();
             shapingPolicy.setEnabled(true);
-            shapingPolicy.setAverageBandwidth((long)networkRateMbps.intValue()*1024L*1024L);
+            shapingPolicy.setAverageBandwidth(networkRateMbps.intValue()*1024L*1024L);
 
             //
             // TODO : people may have different opinion on how to set the following
@@ -1062,10 +1063,10 @@ public class HypervisorHostHelper {
     }
     
     private static void createNvpPortGroup(HostMO hostMo, HostVirtualSwitch vSwitch, String networkName, HostNetworkTrafficShapingPolicy shapingPolicy) throws Exception {
-        /** 
+        /**
          * No portgroup created yet for this nic
          * We need to find an unused vlan and create the pg
-         * The vlan is limited to this vSwitch and the NVP vAPP, 
+         * The vlan is limited to this vSwitch and the NVP vAPP,
          * so no relation to the other vlans in use in CloudStack.
          */
         String vSwitchName = vSwitch.getName();
@@ -1096,7 +1097,7 @@ public class HypervisorHostHelper {
         secPolicy.setMacChanges(Boolean.FALSE);
         
         // Create a portgroup with the uuid of the nic and the vlanid found above
-        hostMo.createPortGroup(vSwitch, networkName, nvpVlanId, secPolicy, shapingPolicy);      
+        hostMo.createPortGroup(vSwitch, networkName, nvpVlanId, secPolicy, shapingPolicy);
     }
 
     public static ManagedObjectReference waitForNetworkReady(HostMO hostMo,


[10/10] git commit: updated refs/heads/master to f5e5b39

Posted by ah...@apache.org.
Moved the DB layer code into framework-db and change only the necessary projects to refer to it.  Cut down on the dependencies introduced with all the code in utils.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/f5e5b39c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/f5e5b39c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/f5e5b39c

Branch: refs/heads/master
Commit: f5e5b39c9bc8d0e719dbb27cb8228b868c6f726f
Parents: 81b121b
Author: Alex Huang <al...@citrix.com>
Authored: Fri Jul 26 15:01:58 2013 -0700
Committer: Alex Huang <al...@citrix.com>
Committed: Fri Jul 26 15:02:10 2013 -0700

----------------------------------------------------------------------
 api/pom.xml                                     |   21 +-
 .../api/response/ServiceOfferingResponse.java   |    5 +-
 api/src/org/apache/cloudstack/usage/Usage.java  |   13 +-
 .../cloudstack/test/utils/SpringUtils.java      |  113 ++
 awsapi/pom.xml                                  |    5 +
 engine/api/pom.xml                              |    5 +
 engine/schema/pom.xml                           |    5 +
 engine/storage/integration-test/pom.xml         |    2 +-
 framework/cluster/pom.xml                       |    5 +
 framework/db/pom.xml                            |   24 +
 .../db/src/com/cloud/dao/EntityManagerImpl.java |  125 ++
 .../utils/crypt/EncryptionSecretKeyChanger.java |  427 ++++
 .../db/src/com/cloud/utils/db/Attribute.java    |  253 +++
 .../com/cloud/utils/db/ConnectionConcierge.java |  223 +++
 .../utils/db/ConnectionConciergeMBean.java      |   30 +
 framework/db/src/com/cloud/utils/db/DB.java     |   59 +
 framework/db/src/com/cloud/utils/db/DbUtil.java |  342 ++++
 framework/db/src/com/cloud/utils/db/EcInfo.java |  106 +
 .../db/src/com/cloud/utils/db/Encrypt.java      |   32 +
 framework/db/src/com/cloud/utils/db/Filter.java |  115 ++
 .../db/src/com/cloud/utils/db/GenericDao.java   |  284 +++
 .../src/com/cloud/utils/db/GenericDaoBase.java  | 1890 ++++++++++++++++++
 .../cloud/utils/db/GenericSearchBuilder.java    |  548 +++++
 .../db/src/com/cloud/utils/db/GlobalLock.java   |  244 +++
 .../db/src/com/cloud/utils/db/GroupBy.java      |  108 +
 .../db/src/com/cloud/utils/db/JoinBuilder.java  |   79 +
 .../db/src/com/cloud/utils/db/JoinType.java     |   32 +
 .../db/src/com/cloud/utils/db/Merovingian2.java |  461 +++++
 .../com/cloud/utils/db/MerovingianMBean.java    |   32 +
 .../db/src/com/cloud/utils/db/ScriptRunner.java |  233 +++
 .../src/com/cloud/utils/db/SearchBuilder.java   |   64 +
 .../src/com/cloud/utils/db/SearchCriteria.java  |  364 ++++
 .../src/com/cloud/utils/db/SearchCriteria2.java |  213 ++
 .../cloud/utils/db/SearchCriteriaService.java   |   29 +
 .../src/com/cloud/utils/db/SequenceFetcher.java |  171 ++
 .../db/src/com/cloud/utils/db/SqlGenerator.java |  669 +++++++
 .../db/src/com/cloud/utils/db/StateMachine.java |   30 +
 .../db/src/com/cloud/utils/db/Transaction.java  | 1174 +++++++++++
 .../cloud/utils/db/TransactionAttachment.java   |   34 +
 .../utils/db/TransactionContextBuilder.java     |   65 +
 .../com/cloud/utils/db/TransactionMBean.java    |   33 +
 .../cloud/utils/db/TransactionMBeanImpl.java    |  113 ++
 .../src/com/cloud/utils/db/UpdateBuilder.java   |  147 ++
 .../db/src/com/cloud/utils/db/UpdateFilter.java |   29 +
 .../com/cloud/utils/db/DbAnnotatedBase.java     |   44 +
 .../cloud/utils/db/DbAnnotatedBaseDerived.java  |   27 +
 .../db/test/com/cloud/utils/db/DbTestDao.java   |   66 +
 .../db/test/com/cloud/utils/db/DbTestUtils.java |   90 +
 .../db/test/com/cloud/utils/db/DbTestVO.java    |   56 +
 .../test/com/cloud/utils/db/DummyComponent.java |   27 +
 .../cloud/utils/db/ElementCollectionTest.java   |   72 +
 .../test/com/cloud/utils/db/GlobalLockTest.java |   81 +
 .../com/cloud/utils/db/Merovingian2Test.java    |   77 +
 .../utils/db/TransactionContextBuilderTest.java |   63 +
 .../com/cloud/utils/db/TransactionTest.java     |  214 ++
 plugins/hypervisors/vmware/pom.xml              |   10 -
 plugins/pom.xml                                 |    2 +-
 server/pom.xml                                  |    2 +-
 server/src/com/cloud/api/ApiDispatcher.java     |    2 +-
 server/src/com/cloud/api/ApiResponseHelper.java |   74 +-
 server/src/com/cloud/dao/EntityManagerImpl.java |  150 --
 usage/pom.xml                                   |    2 +-
 utils/pom.xml                                   |    5 -
 utils/src/com/cloud/utils/AnnotationHelper.java |   57 -
 .../utils/crypt/EncryptionSecretKeyChanger.java |  427 ----
 utils/src/com/cloud/utils/db/Attribute.java     |  253 ---
 .../com/cloud/utils/db/ConnectionConcierge.java |  223 ---
 .../utils/db/ConnectionConciergeMBean.java      |   30 -
 utils/src/com/cloud/utils/db/DB.java            |   59 -
 utils/src/com/cloud/utils/db/DbUtil.java        |  342 ----
 utils/src/com/cloud/utils/db/EcInfo.java        |  106 -
 utils/src/com/cloud/utils/db/Encrypt.java       |   32 -
 utils/src/com/cloud/utils/db/EntityManager.java |   33 -
 utils/src/com/cloud/utils/db/Filter.java        |  115 --
 utils/src/com/cloud/utils/db/GenericDao.java    |  284 ---
 .../src/com/cloud/utils/db/GenericDaoBase.java  | 1890 ------------------
 .../cloud/utils/db/GenericSearchBuilder.java    |  548 -----
 utils/src/com/cloud/utils/db/GlobalLock.java    |  244 ---
 utils/src/com/cloud/utils/db/GroupBy.java       |  108 -
 utils/src/com/cloud/utils/db/JoinBuilder.java   |   79 -
 utils/src/com/cloud/utils/db/JoinType.java      |   32 -
 utils/src/com/cloud/utils/db/Merovingian2.java  |  461 -----
 .../com/cloud/utils/db/MerovingianMBean.java    |   32 -
 utils/src/com/cloud/utils/db/ScriptRunner.java  |  233 ---
 utils/src/com/cloud/utils/db/SearchBuilder.java |   64 -
 .../src/com/cloud/utils/db/SearchCriteria.java  |  364 ----
 .../src/com/cloud/utils/db/SearchCriteria2.java |  213 --
 .../cloud/utils/db/SearchCriteriaService.java   |   29 -
 .../src/com/cloud/utils/db/SequenceFetcher.java |  171 --
 utils/src/com/cloud/utils/db/SqlGenerator.java  |  669 -------
 utils/src/com/cloud/utils/db/StateMachine.java  |   30 -
 utils/src/com/cloud/utils/db/Transaction.java   | 1174 -----------
 .../cloud/utils/db/TransactionAttachment.java   |   34 -
 .../utils/db/TransactionContextBuilder.java     |   65 -
 .../com/cloud/utils/db/TransactionMBean.java    |   33 -
 .../cloud/utils/db/TransactionMBeanImpl.java    |  113 --
 utils/src/com/cloud/utils/db/UpdateBuilder.java |  147 --
 utils/src/com/cloud/utils/db/UpdateFilter.java  |   29 -
 .../com/cloud/utils/db/DbAnnotatedBase.java     |   44 -
 .../cloud/utils/db/DbAnnotatedBaseDerived.java  |   27 -
 utils/test/com/cloud/utils/db/DbTestDao.java    |   66 -
 utils/test/com/cloud/utils/db/DbTestUtils.java  |   90 -
 utils/test/com/cloud/utils/db/DbTestVO.java     |   56 -
 .../test/com/cloud/utils/db/DummyComponent.java |   27 -
 .../cloud/utils/db/ElementCollectionTest.java   |   72 -
 .../test/com/cloud/utils/db/GlobalLockTest.java |   83 -
 .../com/cloud/utils/db/Merovingian2Test.java    |   77 -
 .../utils/db/TransactionContextBuilderTest.java |   63 -
 .../com/cloud/utils/db/TransactionTest.java     |  214 --
 .../utils/log/CglibThrowableRendererTest.java   |  104 -
 .../cloudstack/test/utils/SpringUtils.java      |  113 --
 vmware-base/pom.xml                             |    5 +
 .../vmware/mo/HypervisorHostHelper.java         |   81 +-
 113 files changed, 9842 insertions(+), 10023 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/api/pom.xml
----------------------------------------------------------------------
diff --git a/api/pom.xml b/api/pom.xml
index 8ca258f..3867e71 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -36,10 +36,27 @@
       <artifactId>gson</artifactId>
       <version>${cs.gson.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-db</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
index 288f76b..41a9b79 100644
--- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
@@ -18,7 +18,7 @@ package org.apache.cloudstack.api.response;
 
 import java.util.Date;
 
-import javax.persistence.Column;
+import com.google.gson.annotations.SerializedName;
 
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseResponse;
@@ -26,7 +26,6 @@ import org.apache.cloudstack.api.EntityReference;
 
 import com.cloud.offering.ServiceOffering;
 import com.cloud.serializer.Param;
-import com.google.gson.annotations.SerializedName;
 
 @EntityReference(value = ServiceOffering.class)
 public class ServiceOfferingResponse extends BaseResponse {
@@ -141,7 +140,7 @@ public class ServiceOfferingResponse extends BaseResponse {
     }
 
     public void setSystemVmType(String vmtype) {
-        this.vm_type = vmtype;
+        vm_type = vmtype;
     }
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/api/src/org/apache/cloudstack/usage/Usage.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/usage/Usage.java b/api/src/org/apache/cloudstack/usage/Usage.java
index 23f9d42..1bb1e90 100644
--- a/api/src/org/apache/cloudstack/usage/Usage.java
+++ b/api/src/org/apache/cloudstack/usage/Usage.java
@@ -16,19 +16,8 @@
 // under the License.
 package org.apache.cloudstack.usage;
 
-import org.apache.cloudstack.api.InternalIdentity;
-
 import java.util.Date;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
 public interface Usage {
 	
 	public long getId();
@@ -39,7 +28,7 @@ public interface Usage {
 
     public Long getDomainId();
 
-	public String getDescription();
+    public String getDescription();
 
 	public String getUsageDisplay();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/api/test/org/apache/cloudstack/test/utils/SpringUtils.java
----------------------------------------------------------------------
diff --git a/api/test/org/apache/cloudstack/test/utils/SpringUtils.java b/api/test/org/apache/cloudstack/test/utils/SpringUtils.java
new file mode 100644
index 0000000..220bd80
--- /dev/null
+++ b/api/test/org/apache/cloudstack/test/utils/SpringUtils.java
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.test.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ComponentInstantiationPostProcessor;
+import com.cloud.utils.component.ComponentMethodInterceptor;
+import com.cloud.utils.db.TransactionContextBuilder;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class SpringUtils {
+
+    /**
+     * This method allows you to use @ComponentScan for your unit testing but
+     * it limits the scope of the classes found to the class specified in
+     * the @ComponentScan annotation.
+     *
+     * Without using this method, the default behavior of @ComponentScan is
+     * to actually scan in the package of the class specified rather than
+     * only the class. This can cause extra classes to be loaded which causes
+     * the classes these extra classes depend on to be loaded. The end effect
+     * is often most of the project gets loaded.
+     *
+     * In order to use this method properly, you must do the following: <li>
+     *   - Specify @ComponentScan with basePackageClasses, includeFilters, and
+     *     useDefaultFilters=true.  See the following example.
+     *
+     * <pre>
+     *     @ComponentScan(basePackageClasses={AffinityGroupServiceImpl.class, EventUtils.class},
+     *     includeFilters={@Filter(value=TestConfiguration.Library.class, type=FilterType.CUSTOM)},
+     *     useDefaultFilters=false)
+     * </pre>
+     *
+     *   - Create a Library class and use that to call this method.  See the
+     *     following example.  The Library class you define here is the Library
+     *     class being added in the filter above.
+     *
+     * <pre>
+     * public static class Library implements TypeFilter {
+     *      @Override
+     *      public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+     *          ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+     *          return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+     *      }
+     * }
+     * </pre>
+     *
+     * @param clazzName name of the class that should be included in the Spring components
+     * @param cs ComponentScan annotation that was declared on the configuration
+     *
+     * @return
+     */
+    public static boolean includedInBasePackageClasses(String clazzName, ComponentScan cs) {
+        Class<?> clazzToCheck;
+        try {
+            clazzToCheck = Class.forName(clazzName);
+        } catch (ClassNotFoundException e) {
+            throw new CloudRuntimeException("Unable to find " + clazzName);
+        }
+        Class<?>[] clazzes = cs.basePackageClasses();
+        for (Class<?> clazz : clazzes) {
+            if (clazzToCheck.isAssignableFrom(clazz)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static class CloudStackTestConfiguration {
+
+        @Bean
+        public ComponentContext componentContext() {
+            return new ComponentContext();
+        }
+
+        @Bean
+        public TransactionContextBuilder transactionContextBuilder() {
+            return new TransactionContextBuilder();
+        }
+
+        @Bean
+        public ComponentInstantiationPostProcessor instantiatePostProcessor() {
+            ComponentInstantiationPostProcessor processor = new ComponentInstantiationPostProcessor();
+
+            List<ComponentMethodInterceptor> interceptors = new ArrayList<ComponentMethodInterceptor>();
+            interceptors.add(new TransactionContextBuilder());
+            processor.setInterceptors(interceptors);
+
+            return processor;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/awsapi/pom.xml
----------------------------------------------------------------------
diff --git a/awsapi/pom.xml b/awsapi/pom.xml
index 2fe2089..317d1ce 100644
--- a/awsapi/pom.xml
+++ b/awsapi/pom.xml
@@ -289,6 +289,11 @@
       <artifactId>javassist</artifactId>
       <version>3.9.0.GA</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-db</artifactId>
+      <version>${project.version}</version>
+    </dependency>    
   </dependencies>
   <build>
     <resources>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/engine/api/pom.xml
----------------------------------------------------------------------
diff --git a/engine/api/pom.xml b/engine/api/pom.xml
index 1b8f26c..ccea255 100644
--- a/engine/api/pom.xml
+++ b/engine/api/pom.xml
@@ -27,6 +27,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-db</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-api</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/engine/schema/pom.xml
----------------------------------------------------------------------
diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml
index da40d9c..a9ad13f 100644
--- a/engine/schema/pom.xml
+++ b/engine/schema/pom.xml
@@ -43,6 +43,11 @@
       <artifactId>cloud-engine-components-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-db</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <defaultGoal>install</defaultGoal>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/engine/storage/integration-test/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml
index 4df4451..d082710 100644
--- a/engine/storage/integration-test/pom.xml
+++ b/engine/storage/integration-test/pom.xml
@@ -64,7 +64,7 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
+      <artifactId>cloud-api</artifactId>
       <version>${project.version}</version>
       <type>test-jar</type>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/cluster/pom.xml
----------------------------------------------------------------------
diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml
index 116b635..131511d 100644
--- a/framework/cluster/pom.xml
+++ b/framework/cluster/pom.xml
@@ -24,5 +24,10 @@
       <artifactId>cloud-utils</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-db</artifactId>
+      <version>${project.version}</version>
+    </dependency>    
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/pom.xml
----------------------------------------------------------------------
diff --git a/framework/db/pom.xml b/framework/db/pom.xml
index b4011c7..c23f96f 100644
--- a/framework/db/pom.xml
+++ b/framework/db/pom.xml
@@ -20,9 +20,33 @@
   </parent>
   <dependencies>
     <dependency>
+      <groupId>javax.ejb</groupId>
+      <artifactId>ejb-api</artifactId>
+      <version>${cs.ejb.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>javax.persistence</artifactId>
+      <version>${cs.jpa.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-utils</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>com/cloud/utils/testcase/*TestCase*</exclude>
+            <exclude>com/cloud/utils/db/*Test*</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/dao/EntityManagerImpl.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/dao/EntityManagerImpl.java b/framework/db/src/com/cloud/dao/EntityManagerImpl.java
new file mode 100644
index 0000000..bb493c0
--- /dev/null
+++ b/framework/db/src/com/cloud/dao/EntityManagerImpl.java
@@ -0,0 +1,125 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.dao;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import net.sf.ehcache.Cache;
+
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Local(value=EntityManager.class)
+@SuppressWarnings("unchecked")
+public class EntityManagerImpl extends ManagerBase implements EntityManager {
+    String _name;
+    Cache _cache;
+
+    @Override
+    public <T, K extends Serializable> T findById(Class<T> entityType, K id) {
+        GenericDao<? extends T, K> dao = (GenericDao<? extends T, K>)GenericDaoBase.getDao(entityType);
+        return dao.findById(id);
+    }
+    
+    public <T, K extends Serializable> T findByIdIncludingRemoved(Class<T> entityType, K id) {
+        GenericDao<? extends T, K> dao = (GenericDao<? extends T, K>)GenericDaoBase.getDao(entityType);
+        return dao.findByIdIncludingRemoved(id);
+    }
+
+    @Override
+    public <T> T findByUuid(Class<T> entityType, String uuid) {
+        // Finds and returns a unique VO using uuid, null if entity not found in db
+        GenericDao<? extends T, String> dao = (GenericDao<? extends T, String>)GenericDaoBase.getDao(entityType);
+        return dao.findByUuid(uuid);
+    }
+
+    public <T> T findByUuidIncludingRemoved(Class<T> entityType, String uuid) {
+        // Finds and returns a unique VO using uuid, null if entity not found in db
+        GenericDao<? extends T, String> dao = (GenericDao<? extends T, String>)GenericDaoBase.getDao(entityType);
+        return dao.findByUuidIncludingRemoved(uuid);
+    }
+
+    @Override
+    public <T> T findByXId(Class<T> entityType, String xid) {
+        return null;
+    }
+
+    @Override
+    public <T> List<? extends T> list(Class<T> entityType) {
+        GenericDao<? extends T, ? extends Serializable> dao = GenericDaoBase.getDao(entityType);
+        return dao.listAll();
+    }
+
+    public <T> T persist(T t) {
+        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao((Class<T>)t.getClass());
+        return dao.persist(t);
+    }
+
+    public <T> SearchBuilder<T> createSearchBuilder(Class<T> entityType) {
+        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
+        return dao.createSearchBuilder();
+    }
+
+    public <T, K> GenericSearchBuilder<T, K> createGenericSearchBuilder(Class<T> entityType, Class<K> resultType) {
+        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
+        return dao.createSearchBuilder((Class<K>)resultType.getClass());
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+        
+        return true;
+    } 
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    public <T, K> List<K> search(Class<T> entityType, SearchCriteria<K> sc) {
+        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
+        return dao.customSearch(sc, null);
+    }
+
+    @Override
+    public <T, K extends Serializable> void remove(Class<T> entityType, K id) {
+        GenericDao<T, K> dao = (GenericDao<T, K>)GenericDaoBase.getDao(entityType);
+        dao.remove(id);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
new file mode 100755
index 0000000..9b13eb8
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
@@ -0,0 +1,427 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.crypt;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
+import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
+import org.jasypt.exceptions.EncryptionOperationNotPossibleException;
+import org.jasypt.properties.EncryptableProperties;
+
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+/*
+ * EncryptionSecretKeyChanger updates Management Secret Key / DB Secret Key or both.
+ * DB secret key is validated against the key in db.properties
+ * db.properties is updated with values encrypted using new MS secret key
+ * DB data migrated using new DB secret key
+ */
+public class EncryptionSecretKeyChanger {
+
+	private StandardPBEStringEncryptor oldEncryptor = new StandardPBEStringEncryptor();
+	private StandardPBEStringEncryptor newEncryptor = new StandardPBEStringEncryptor();
+	private static final String keyFile = "/etc/cloudstack/management/key";
+
+	public static void main(String[] args){
+		List<String> argsList = Arrays.asList(args);
+		Iterator<String> iter = argsList.iterator();
+		String oldMSKey = null;
+		String oldDBKey = null;
+		String newMSKey = null; 
+		String newDBKey = null;
+
+		//Parse command-line args
+		while (iter.hasNext()) {
+			String arg = iter.next();
+			// Old MS Key
+			if (arg.equals("-m")) {
+				oldMSKey = iter.next();
+			}
+			// Old DB Key
+			if (arg.equals("-d")) {
+				oldDBKey = iter.next();
+			}
+			// New MS Key
+			if (arg.equals("-n")) {
+				newMSKey = iter.next();
+			}
+			// New DB Key
+			if (arg.equals("-e")) {
+				newDBKey = iter.next();
+			}
+		}
+
+		if(oldMSKey == null || oldDBKey ==null){
+			System.out.println("Existing MS secret key or DB secret key is not provided");
+			usage();
+			return;
+		}
+
+		if(newMSKey == null && newDBKey ==null){
+			System.out.println("New MS secret key and DB secret are both not provided");
+			usage();
+			return;
+		}
+
+		final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
+		final Properties dbProps;
+		EncryptionSecretKeyChanger keyChanger = new EncryptionSecretKeyChanger();
+		StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
+		keyChanger.initEncryptor(encryptor, oldMSKey);
+		dbProps = new EncryptableProperties(encryptor);
+		PropertiesConfiguration backupDBProps = null;
+
+		System.out.println("Parsing db.properties file");
+		try {
+			dbProps.load(new FileInputStream(dbPropsFile));
+			backupDBProps = new PropertiesConfiguration(dbPropsFile);
+		} catch (FileNotFoundException e) {
+			System.out.println("db.properties file not found while reading DB secret key" +e.getMessage());
+		} catch (IOException e) {
+			System.out.println("Error while reading DB secret key from db.properties" +e.getMessage());
+		} catch (ConfigurationException e) {
+			e.printStackTrace();
+		}
+		
+		String dbSecretKey = null;
+		try {
+			dbSecretKey = dbProps.getProperty("db.cloud.encrypt.secret");
+		} catch (EncryptionOperationNotPossibleException e) {
+			System.out.println("Failed to decrypt existing DB secret key from db.properties. "+e.getMessage());
+			return;
+		}
+		
+		if(!oldDBKey.equals(dbSecretKey)){
+			System.out.println("Incorrect MS Secret Key or DB Secret Key");
+			return;
+		}
+
+		System.out.println("Secret key provided matched the key in db.properties");
+		final String encryptionType = dbProps.getProperty("db.cloud.encryption.type");
+		
+		if(newMSKey == null){
+			System.out.println("No change in MS Key. Skipping migrating db.properties");
+		} else {
+			if(!keyChanger.migrateProperties(dbPropsFile, dbProps, newMSKey, newDBKey)){
+				System.out.println("Failed to update db.properties");
+				return;
+			} else {
+				//db.properties updated successfully
+				if(encryptionType.equals("file")){
+					//update key file with new MS key
+					try {
+						FileWriter fwriter = new FileWriter(keyFile);
+						BufferedWriter bwriter = new BufferedWriter(fwriter); 
+						bwriter.write(newMSKey);
+						bwriter.close();
+					} catch (IOException e) {
+						System.out.println("Failed to write new secret to file. Please update the file manually");
+					} 
+				}
+			}
+		}
+		
+		boolean success = false;
+		if(newDBKey == null || newDBKey.equals(oldDBKey)){
+			System.out.println("No change in DB Secret Key. Skipping Data Migration");
+		} else {
+			EncryptionSecretKeyChecker.initEncryptorForMigration(oldMSKey);
+			try {
+				success = keyChanger.migrateData(oldDBKey, newDBKey);
+			} catch (Exception e) {
+				System.out.println("Error during data migration");
+				e.printStackTrace();
+				success = false;
+			}
+		}
+		
+		if(success){
+			System.out.println("Successfully updated secret key(s)");
+		}
+		else {
+			System.out.println("Data Migration failed. Reverting db.properties");
+			//revert db.properties
+			try {
+				backupDBProps.save();
+			} catch (ConfigurationException e) {
+				e.printStackTrace();
+			}
+			if(encryptionType.equals("file")){
+				//revert secret key in file
+				try {
+					FileWriter fwriter = new FileWriter(keyFile);
+					BufferedWriter bwriter = new BufferedWriter(fwriter); 
+					bwriter.write(oldMSKey);
+					bwriter.close();
+				} catch (IOException e) {
+					System.out.println("Failed to revert to old secret to file. Please update the file manually");
+				} 
+			}
+		}
+	}
+	
+	private boolean migrateProperties(File dbPropsFile, Properties dbProps, String newMSKey, String newDBKey){
+		System.out.println("Migrating db.properties..");
+		StandardPBEStringEncryptor msEncryptor = new StandardPBEStringEncryptor();;
+		initEncryptor(msEncryptor, newMSKey);
+		
+		try {
+			PropertiesConfiguration newDBProps = new PropertiesConfiguration(dbPropsFile);
+			if(newDBKey!=null && !newDBKey.isEmpty()){
+				newDBProps.setProperty("db.cloud.encrypt.secret", "ENC("+msEncryptor.encrypt(newDBKey)+")");
+			}
+			String prop = dbProps.getProperty("db.cloud.password");
+			if(prop!=null && !prop.isEmpty()){
+				newDBProps.setProperty("db.cloud.password", "ENC("+msEncryptor.encrypt(prop)+")");
+			}
+			prop = dbProps.getProperty("db.usage.password");
+			if(prop!=null && !prop.isEmpty()){
+				newDBProps.setProperty("db.usage.password", "ENC("+msEncryptor.encrypt(prop)+")");
+			}
+			newDBProps.save(dbPropsFile.getAbsolutePath());
+		} catch (Exception e) { 		
+			e.printStackTrace();
+			return false;
+		}
+		System.out.println("Migrating db.properties Done.");
+		return true;
+	}
+
+	private boolean migrateData(String oldDBKey, String newDBKey){
+		System.out.println("Begin Data migration");
+		initEncryptor(oldEncryptor, oldDBKey);
+		initEncryptor(newEncryptor, newDBKey);
+		System.out.println("Initialised Encryptors");
+		
+		Transaction txn = Transaction.open("Migrate");
+		txn.start();
+		try {
+			Connection conn;
+			try {
+				conn = txn.getConnection();
+			} catch (SQLException e) {
+				throw new CloudRuntimeException("Unable to migrate encrypted data in the database", e);
+			}
+
+			migrateConfigValues(conn);
+			migrateHostDetails(conn);
+			migrateVNCPassword(conn);
+			migrateUserCredentials(conn);
+
+			txn.commit();
+		} finally {
+			txn.close();
+		}
+		System.out.println("End Data migration");
+		return true;
+	}
+
+	private void initEncryptor(StandardPBEStringEncryptor encryptor, String secretKey){
+		encryptor.setAlgorithm("PBEWithMD5AndDES");
+		SimpleStringPBEConfig stringConfig = new SimpleStringPBEConfig();
+		stringConfig.setPassword(secretKey);
+		encryptor.setConfig(stringConfig);
+	}
+
+	private String migrateValue(String value){
+		if(value ==null || value.isEmpty()){
+			return value;
+		}
+		String decryptVal = oldEncryptor.decrypt(value);
+		return newEncryptor.encrypt(decryptVal);
+	}
+
+	private void migrateConfigValues(Connection conn) {
+		System.out.println("Begin migrate config values");
+		PreparedStatement pstmt = null;
+		ResultSet rs = null;
+		try {
+			pstmt = conn.prepareStatement("select name, value from configuration where category in ('Hidden', 'Secure')");
+			rs = pstmt.executeQuery();
+			while (rs.next()) {
+				String name = rs.getString(1);
+				String value = rs.getString(2);
+				if(value == null || value.isEmpty()){
+					continue;
+				}
+				String encryptedValue = migrateValue(value);
+				pstmt = conn.prepareStatement("update configuration set value=? where name=?");
+				pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
+				pstmt.setString(2, name);
+				pstmt.executeUpdate();
+			}
+		} catch (SQLException e) {
+			throw new CloudRuntimeException("Unable to update configuration values ", e);
+		} catch (UnsupportedEncodingException e) {
+			throw new CloudRuntimeException("Unable to update configuration values ", e);
+		} finally {
+			try {
+				if (rs != null) {
+					rs.close(); 
+				}
+
+				if (pstmt != null) {
+					pstmt.close();
+				}
+			} catch (SQLException e) {
+			}
+		}
+		System.out.println("End migrate config values");
+	}
+
+	private void migrateHostDetails(Connection conn) {
+		System.out.println("Begin migrate host details");
+		PreparedStatement pstmt = null;
+		ResultSet rs = null;
+		try {
+			pstmt = conn.prepareStatement("select id, value from host_details where name = 'password'");
+			rs = pstmt.executeQuery();
+			while (rs.next()) {
+				long id = rs.getLong(1);
+				String value = rs.getString(2);
+				if(value == null || value.isEmpty()){
+					continue;
+				}
+				String encryptedValue = migrateValue(value);
+				pstmt = conn.prepareStatement("update host_details set value=? where id=?");
+				pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
+				pstmt.setLong(2, id);
+				pstmt.executeUpdate();
+			}
+		} catch (SQLException e) {
+			throw new CloudRuntimeException("Unable update host_details values ", e);
+		} catch (UnsupportedEncodingException e) {
+			throw new CloudRuntimeException("Unable update host_details values ", e);
+		} finally {
+			try {
+				if (rs != null) {
+					rs.close(); 
+				}
+
+				if (pstmt != null) {
+					pstmt.close();
+				}
+			} catch (SQLException e) {
+			}
+		}
+		System.out.println("End migrate host details");
+	}
+
+	private void migrateVNCPassword(Connection conn) {
+		System.out.println("Begin migrate VNC password");
+		PreparedStatement pstmt = null;
+		ResultSet rs = null;
+		try {
+			pstmt = conn.prepareStatement("select id, vnc_password from vm_instance");
+			rs = pstmt.executeQuery();
+			while (rs.next()) {
+				long id = rs.getLong(1);
+				String value = rs.getString(2);
+				if(value == null || value.isEmpty()){
+					continue;
+				}
+				String encryptedValue = migrateValue(value);
+				pstmt = conn.prepareStatement("update vm_instance set vnc_password=? where id=?");
+				pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
+				pstmt.setLong(2, id);
+				pstmt.executeUpdate();
+			}
+		} catch (SQLException e) {
+			throw new CloudRuntimeException("Unable update vm_instance vnc_password ", e);
+		} catch (UnsupportedEncodingException e) {
+			throw new CloudRuntimeException("Unable update vm_instance vnc_password ", e);
+		} finally {
+			try {
+				if (rs != null) {
+					rs.close(); 
+				}
+
+				if (pstmt != null) {
+					pstmt.close();
+				}
+			} catch (SQLException e) {
+			}
+		}
+		System.out.println("End migrate VNC password");
+	}
+
+	private void migrateUserCredentials(Connection conn) {
+		System.out.println("Begin migrate user credentials");
+		PreparedStatement pstmt = null;
+		ResultSet rs = null;
+		try {
+			pstmt = conn.prepareStatement("select id, secret_key from user");
+			rs = pstmt.executeQuery();
+			while (rs.next()) {
+				long id = rs.getLong(1);
+				String secretKey = rs.getString(2);
+				if(secretKey == null || secretKey.isEmpty()){
+					continue;
+				}
+				String encryptedSecretKey = migrateValue(secretKey);
+				pstmt = conn.prepareStatement("update user set secret_key=? where id=?");
+				pstmt.setBytes(1, encryptedSecretKey.getBytes("UTF-8"));
+				pstmt.setLong(2, id);
+				pstmt.executeUpdate();
+			}
+		} catch (SQLException e) {
+			throw new CloudRuntimeException("Unable update user secret key ", e);
+		} catch (UnsupportedEncodingException e) {
+			throw new CloudRuntimeException("Unable update user secret key ", e);
+		} finally {
+			try {
+				if (rs != null) {
+					rs.close(); 
+				}
+
+				if (pstmt != null) {
+					pstmt.close();
+				}
+			} catch (SQLException e) {
+			}
+		}
+		System.out.println("End migrate user credentials");
+	}
+
+	private static void usage(){
+		System.out.println("Usage: \tEncryptionSecretKeyChanger \n" +
+				"\t\t-m <Mgmt Secret Key> \n" +
+				"\t\t-d <DB Secret Key> \n" +
+				"\t\t-n [New Mgmt Secret Key] \n" +
+				"\t\t-e [New DB Secret Key]");
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/Attribute.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/Attribute.java b/framework/db/src/com/cloud/utils/db/Attribute.java
new file mode 100755
index 0000000..22fd969
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/Attribute.java
@@ -0,0 +1,253 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Field;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+/**
+ * The Java annotation are somewhat incomplete.  This gives better information
+ * about exactly what each field has.
+ *
+ */
+public class Attribute {
+    public enum Flag {
+        Insertable(0x01),
+        Updatable(0x02),
+        Nullable(0x04),
+        DaoGenerated(0x08),
+        DbGenerated(0x10),
+        Embedded(0x20),
+        Id(0x40),
+        Selectable(0x80),
+        Time(0x100),
+        Date(0x200),
+        TimeStamp(0x400),
+        SequenceGV(0x1000),
+        TableGV(0x2000),
+        AutoGV(0x4000),
+        Created(0x10000),
+        Removed(0x20000),
+        DC(0x40000),
+        CharDT(0x100000),
+        StringDT(0x200000),
+        IntegerDT(0x400000),
+        Encrypted(0x800000);
+
+        int place;
+        Flag(int place) {
+            this.place = place;
+        }
+
+        public int place() {
+            return place;
+        }
+
+        public boolean check(int value) {
+            return (value & place) == place;
+        }
+
+        public int setTrue(int value) {
+            return (value | place);
+        }
+
+        public int setFalse(int value) {
+            return (value & ~place);
+        }
+    }
+
+    protected String table;
+    protected String columnName;
+    protected Field field;
+    protected int flags;
+    protected Column column;
+    protected Object attache;
+
+    public Attribute(Class<?> clazz, AttributeOverride[] overrides, Field field, String tableName, boolean isEmbedded, boolean isId) {
+        this.field = field;
+        flags = 0;
+        table = tableName;
+        setupColumnInfo(clazz, overrides, tableName, isEmbedded, isId);
+    }
+
+    public Attribute(String table, String columnName) {
+        this.table = table;
+        this.columnName = columnName;
+        this.field = null;
+        this.column = null;
+    }
+
+    protected void setupColumnInfo(Class<?> clazz, AttributeOverride[] overrides, String tableName, boolean isEmbedded, boolean isId) {
+        flags = Flag.Selectable.setTrue(flags);
+        GeneratedValue gv = field.getAnnotation(GeneratedValue.class);
+        if (gv != null) {
+            if (gv.strategy() == GenerationType.IDENTITY) {
+                flags = Flag.DbGenerated.setTrue(flags);
+            } else if (gv.strategy() == GenerationType.SEQUENCE) {
+                assert (false) : "Sequence generation not supported.";
+                flags = Flag.DaoGenerated.setTrue(flags);
+                flags = Flag.Insertable.setTrue(flags);
+                flags = Flag.SequenceGV.setTrue(flags);
+            } else if (gv.strategy() == GenerationType.TABLE) {
+                flags = Flag.DaoGenerated.setTrue(flags);
+                flags = Flag.Insertable.setTrue(flags);
+                flags = Flag.TableGV.setTrue(flags);
+            } else if (gv.strategy() == GenerationType.AUTO) {
+                flags = Flag.DaoGenerated.setTrue(flags);
+                flags = Flag.Insertable.setTrue(flags);
+                flags = Flag.AutoGV.setTrue(flags);
+            }
+        }
+
+        if (isEmbedded) {
+            flags = Flag.Embedded.setTrue(flags);
+        }
+
+        if (isId) {
+            flags = Flag.Id.setTrue(flags);
+        } else {
+            Id id = field.getAnnotation(Id.class);
+            if (id != null) {
+                flags = Flag.Id.setTrue(flags);
+            }
+        }
+        column = field.getAnnotation(Column.class);
+        if (gv == null) {
+            if (column == null || (column.insertable() && column.table().length() == 0)) {
+                flags = Flag.Insertable.setTrue(flags);
+            }
+            if (column == null || (column.updatable() && column.table().length() == 0)) {
+                flags = Flag.Updatable.setTrue(flags);
+            }
+            if (column == null || column.nullable()) {
+                flags = Flag.Nullable.setTrue(flags);
+            }
+            Encrypt encrypt = field.getAnnotation(Encrypt.class);
+            if (encrypt != null && encrypt.encrypt()) {
+                flags = Flag.Encrypted.setTrue(flags);
+            }
+        }
+        ElementCollection ec = field.getAnnotation(ElementCollection.class);
+        if (ec != null) {
+            flags = Flag.Insertable.setFalse(flags);
+            flags = Flag.Selectable.setFalse(flags);
+        }
+
+        Temporal temporal = field.getAnnotation(Temporal.class);
+        if (temporal != null) {
+            if (temporal.value() == TemporalType.DATE) {
+                flags = Flag.Date.setTrue(flags);
+            } else if (temporal.value() == TemporalType.TIME) {
+                flags = Flag.Time.setTrue(flags);
+            } else if (temporal.value() == TemporalType.TIMESTAMP) {
+                flags = Flag.TimeStamp.setTrue(flags);
+            }
+        }
+
+        if (column != null && column.table().length() > 0) {
+            table = column.table();
+        }
+
+        columnName = DbUtil.getColumnName(field, overrides);
+    }
+
+    public final boolean isInsertable() {
+        return Flag.Insertable.check(flags);
+    }
+
+    public final boolean isUpdatable() {
+        return Flag.Updatable.check(flags);
+    }
+
+    public final boolean isNullable() {
+        return Flag.Nullable.check(flags);
+    }
+
+    public final boolean isId() {
+        return Flag.Id.check(flags);
+    }
+
+    public final boolean isSelectable() {
+        return Flag.Selectable.check(flags);
+    }
+
+    public final boolean is(Flag flag) {
+        return flag.check(flags);
+    }
+
+    public final void setTrue(Flag flag) {
+        flags = flag.setTrue(flags);
+    }
+
+    public final void setFalse(Flag flag) {
+        flags = flag.setFalse(flags);
+    }
+
+    public final boolean isEncrypted() {
+        return Flag.Encrypted.check(flags);
+    }
+
+    public Field getField() {
+        return field;
+    }
+
+    public Object get(Object entity) {
+        try {
+            return field.get(entity);
+        } catch (IllegalAccessException e) {
+            assert (false) : "How did we get here?";
+            return null;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return columnName.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Attribute)) {
+            return false;
+        }
+
+        Attribute that = (Attribute)obj;
+
+        return columnName.equals(that.columnName) && table.equals(that.table);
+    }
+
+    @Override
+    public String toString() {
+        return table + "." + columnName;
+    }
+
+    public String getColumnName() {
+        return columnName;
+    }
+
+    public void setColumnName(String columnName) {
+        this.columnName = columnName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java b/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
new file mode 100644
index 0000000..0294334
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
@@ -0,0 +1,223 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.StandardMBean;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.mgmt.JmxUtil;
+
+/**
+ * ConnectionConcierge keeps stand alone database connections alive.  This is
+ * needs someone to keep that database connection from being garbage collected
+ * 
+ */
+public class ConnectionConcierge {
+
+    static final Logger s_logger = Logger.getLogger(ConnectionConcierge.class);
+
+    static final ConnectionConciergeManager s_mgr = new ConnectionConciergeManager();
+
+    Connection _conn;
+    String _name;
+    boolean _keepAlive;
+    boolean _autoCommit;
+    int _isolationLevel;
+    int _holdability;
+
+    public ConnectionConcierge(String name, Connection conn, boolean keepAlive) {
+        _name = name + s_mgr.getNextId();
+        _keepAlive = keepAlive;
+        try {
+            _autoCommit = conn.getAutoCommit();
+            _isolationLevel = conn.getTransactionIsolation();
+            _holdability = conn.getHoldability();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to get information from the connection object", e);
+        }
+        reset(conn);
+    }
+
+    public void reset(Connection conn) {
+        try {
+            release();
+        } catch (Throwable th) {
+            s_logger.error("Unable to release a connection", th);
+        }
+        _conn = conn;
+        try {
+            _conn.setAutoCommit(_autoCommit);
+            _conn.setHoldability(_holdability);
+            _conn.setTransactionIsolation(_isolationLevel);
+        } catch (SQLException e) {
+            s_logger.error("Unable to release a connection", e);
+        }
+        s_mgr.register(_name, this);
+        s_logger.debug("Registering a database connection for " + _name);
+    }
+
+    public final Connection conn() {
+        return _conn;
+    }
+
+    public void release() {
+        s_mgr.unregister(_name);
+        try {
+            if (_conn != null) {
+                _conn.close();
+            }
+            _conn = null;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Problem in closing a connection", e);
+        }
+    }
+
+    @Override
+    protected void finalize() throws Exception {
+        if (_conn != null) {
+            release();
+        }
+    }
+
+    public boolean keepAlive() {
+        return _keepAlive;
+    }
+
+    protected static class ConnectionConciergeManager extends StandardMBean implements ConnectionConciergeMBean {
+        ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ConnectionKeeper"));
+        final ConcurrentHashMap<String, ConnectionConcierge> _conns = new ConcurrentHashMap<String, ConnectionConcierge>();
+        final AtomicInteger _idGenerator = new AtomicInteger();
+
+        ConnectionConciergeManager() {
+            super(ConnectionConciergeMBean.class, false);
+            resetKeepAliveTask(20);
+            try {
+                JmxUtil.registerMBean("DB Connections", "DB Connections", this);
+            } catch (Exception e) {
+                s_logger.error("Unable to register mbean", e);
+            }
+        }
+
+        public Integer getNextId() {
+            return _idGenerator.incrementAndGet();
+        }
+
+        public void register(String name, ConnectionConcierge concierge) {
+            _conns.put(name, concierge);
+        }
+
+        public void unregister(String name) {
+            _conns.remove(name);
+        }
+
+        protected String testValidity(String name, Connection conn) {
+            PreparedStatement pstmt = null;
+            try {
+                if (conn != null) {
+                    pstmt = conn.prepareStatement("SELECT 1");
+                    pstmt.executeQuery();
+                }
+                return null;
+            } catch (Throwable th) {
+                s_logger.error("Unable to keep the db connection for " + name, th);
+                return th.toString();
+            } finally {
+                if (pstmt != null) {
+                    try {
+                        pstmt.close();
+                    } catch (SQLException e) {
+                    }
+                }
+            }
+        }
+
+        @Override
+        public List<String> testValidityOfConnections() {
+            ArrayList<String> results = new ArrayList<String>(_conns.size());
+            for (Map.Entry<String, ConnectionConcierge> entry : _conns.entrySet()) {
+                String result = testValidity(entry.getKey(), entry.getValue().conn());
+                results.add(entry.getKey() + "=" + (result == null ? "OK" : result));
+            }
+            return results;
+        }
+
+        @Override
+        public String resetConnection(String name) {
+            ConnectionConcierge concierge = _conns.get(name);
+            if (concierge == null) {
+                return "Not Found";
+            }
+
+            Connection conn = Transaction.getStandaloneConnection();
+            if (conn == null) {
+                return "Unable to get anotehr db connection";
+            }
+
+            concierge.reset(conn);
+            return "Done";
+        }
+
+        @Override
+        public String resetKeepAliveTask(int seconds) {
+            if (_executor != null) {
+                try {
+                    _executor.shutdown();
+                } catch(Exception e) {
+                    s_logger.error("Unable to shutdown executor", e);
+                }
+            }
+
+            _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ConnectionConcierge"));
+
+            _executor.scheduleAtFixedRate(new Runnable() {
+
+                @Override
+                public void run() {
+                    s_logger.trace("connection concierge keep alive task");
+                    for (Map.Entry<String, ConnectionConcierge> entry : _conns.entrySet()) {
+                        ConnectionConcierge concierge = entry.getValue();
+                        if (concierge.keepAlive()) {
+                            testValidity(entry.getKey(), entry.getValue().conn());
+                        }
+                    }
+                }
+            }, 0, seconds, TimeUnit.SECONDS);
+
+            return "As you wish.";
+        }
+
+        @Override
+        public List<String> getConnectionsNotPooled() {
+            return new ArrayList<String>(_conns.keySet());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/ConnectionConciergeMBean.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/ConnectionConciergeMBean.java b/framework/db/src/com/cloud/utils/db/ConnectionConciergeMBean.java
new file mode 100644
index 0000000..19a09cd
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/ConnectionConciergeMBean.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.util.List;
+
+public interface ConnectionConciergeMBean {
+    
+    List<String> testValidityOfConnections();
+    
+    String resetConnection(String name);
+    
+    String resetKeepAliveTask(int seconds);
+    
+    List<String> getConnectionsNotPooled();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/DB.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/DB.java b/framework/db/src/com/cloud/utils/db/DB.java
new file mode 100644
index 0000000..f83a7ea
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/DB.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Running with assertions on, will find all classes that are
+ * 
+ * 1. Annotate method that starts and commits DB transactions.
+ *    Transaction txn = Transaction.currentTxn();
+ *    txn.start();
+ *    ...
+ *    txn.commit();
+ * 
+ * 2. Annotate methods that uses a DAO's acquire method.
+ *    _dao.acquireInLockTable(id);
+ *    ...
+ *    _dao.releaseFromLockTable(id);
+ * 
+ * 3. Annotate methods that are inside a DAO but doesn't use
+ *    the Transaction class.  Generally, these are methods
+ *    that are utility methods for setting up searches.  In
+ *    this case use @DB(txn=false) to annotate the method.
+ *    While this is not required, it helps when you're debugging
+ *    the code and it saves on method calls during runtime.
+ *
+ */
+@Target({TYPE, METHOD})
+@Retention(RUNTIME)
+public @interface DB {
+    /**
+     * (Optional) Specifies that the method
+     * does not use transaction.  This is useful for
+     * utility methods within DAO classes which are
+     * automatically marked with @DB.  By marking txn=false,
+     * the method is not surrounded with transaction code.
+     */
+    boolean txn() default true;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/DbUtil.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/DbUtil.java b/framework/db/src/com/cloud/utils/db/DbUtil.java
new file mode 100755
index 0000000..da0efbb
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/DbUtil.java
@@ -0,0 +1,342 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Id;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.PrimaryKeyJoinColumns;
+import javax.persistence.SecondaryTable;
+import javax.persistence.SecondaryTables;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.log4j.Logger;
+
+public class DbUtil {
+    protected final static Logger s_logger = Logger.getLogger(DbUtil.class);
+    
+    private static Map<String, Connection> s_connectionForGlobalLocks = new HashMap<String, Connection>();
+    
+    public static Connection getConnectionForGlobalLocks(String name, boolean forLock) {
+    	synchronized(s_connectionForGlobalLocks) {
+    		if(forLock) {
+    			if(s_connectionForGlobalLocks.get(name) != null) {
+    				s_logger.error("Sanity check failed, global lock name " + name + " is already in use");
+    				assert(false);
+    			}
+    			
+    			Connection connection = Transaction.getStandaloneConnection();
+    			if(connection != null) {
+    				try {
+						connection.setAutoCommit(true);
+					} catch (SQLException e) {
+						try {
+							connection.close();
+						} catch(SQLException sqlException) {
+						}
+						return null;
+					}
+					s_connectionForGlobalLocks.put(name, connection);
+					return connection;
+    			}
+    	    	return null;
+    		} else {
+    			Connection connection = s_connectionForGlobalLocks.get(name);
+    			s_connectionForGlobalLocks.remove(name);
+    			return connection;
+    		}
+    	}
+    }
+    
+    public static void removeConnectionForGlobalLocks(String name) {
+    	synchronized(s_connectionForGlobalLocks) {
+    		s_connectionForGlobalLocks.remove(name);
+    	}
+    }
+	
+    public static String getColumnName(Field field, AttributeOverride[] overrides) {
+        if (overrides != null) {
+            for (AttributeOverride override : overrides) {
+                if (override.name().equals(field.getName())) {
+                    return override.column().name();
+                }
+            }
+        }
+        
+        assert(field.getAnnotation(Embedded.class) == null) : "Cannot get column name from embedded field: " + field.getName();
+        
+        Column column = field.getAnnotation(Column.class);
+        return column != null ? column.name() : field.getName();
+    }
+    
+    public static String getColumnName(Field field) {
+        return getColumnName(field, null);
+    }
+    
+    public static String getReferenceColumn(PrimaryKeyJoinColumn pkjc) {
+        return pkjc.referencedColumnName().length() != 0
+            ? pkjc.referencedColumnName()
+            : pkjc.name();
+    }
+    
+    public static PrimaryKeyJoinColumn[] getPrimaryKeyJoinColumns(Class<?> clazz) {
+        PrimaryKeyJoinColumn pkjc = clazz.getAnnotation(PrimaryKeyJoinColumn.class);
+        if (pkjc != null) {
+            return new PrimaryKeyJoinColumn[] { pkjc };
+        }
+        
+        PrimaryKeyJoinColumns pkjcs = clazz.getAnnotation(PrimaryKeyJoinColumns.class);
+        if (pkjcs != null) {
+            return pkjcs.value();
+        }
+        
+        return null;
+    }
+    
+    public static Field findField(Class<?> clazz, String columnName) {
+        for (Field field : clazz.getDeclaredFields()) {
+            if (field.getAnnotation(Embedded.class) != null || field.getAnnotation(EmbeddedId.class) != null) {
+                findField(field.getClass(), columnName);
+            } else {
+                if (columnName.equals(DbUtil.getColumnName(field))) {
+                    return field;
+                }
+            }
+        }
+        return null;
+    }
+    
+    public static final AttributeOverride[] getAttributeOverrides(AnnotatedElement ae) {
+        AttributeOverride[] overrides = null;
+        
+        AttributeOverrides aos = ae.getAnnotation(AttributeOverrides.class);
+        if (aos != null) {
+            overrides = aos.value();
+        }
+        
+        if (overrides == null || overrides.length == 0) {
+            AttributeOverride override = ae.getAnnotation(AttributeOverride.class);
+            if (override != null) {
+                overrides = new AttributeOverride[1];
+                overrides[0] = override;
+            } else {
+                overrides = new AttributeOverride[0];
+            }
+        }
+        
+        return overrides;
+    }
+    
+    public static final boolean isPersistable(Field field) {
+        if (field.getAnnotation(Transient.class) != null) {
+            return false;
+        }
+        
+        int modifiers = field.getModifiers();
+        return !(Modifier.isFinal(modifiers) ||
+                 Modifier.isStatic(modifiers) ||
+                 Modifier.isTransient(modifiers));
+    }
+    
+    public static final boolean isIdField(Field field) {
+        if (field.getAnnotation(Id.class) != null) {
+            return true;
+        }
+        
+        if (field.getAnnotation(EmbeddedId.class) != null) {
+            assert (field.getClass().getAnnotation(Embeddable.class) != null) : "Class " + field.getClass().getName() + " must be Embeddable to be used as Embedded Id";
+            return true;
+        }
+        
+        return false;
+    }
+    
+    public static final SecondaryTable[] getSecondaryTables(AnnotatedElement clazz) {
+        SecondaryTable[] sts = null;
+        SecondaryTable stAnnotation = clazz.getAnnotation(SecondaryTable.class);
+        if (stAnnotation == null) {
+            SecondaryTables stsAnnotation = clazz.getAnnotation(SecondaryTables.class);
+            sts = stsAnnotation != null ? stsAnnotation.value() : new SecondaryTable[0];
+        } else {
+            sts = new SecondaryTable[] {stAnnotation};
+        }
+        
+        return sts;
+    }
+    
+    public static final String getTableName(Class<?> clazz) {
+        Table table = clazz.getAnnotation(Table.class);
+        return table != null ? table.name() : clazz.getSimpleName();
+    }
+    
+    public static boolean getGlobalLock(String name, int timeoutSeconds) {
+        Connection conn = getConnectionForGlobalLocks(name, true);
+        if(conn == null) {
+            s_logger.error("Unable to acquire DB connection for global lock system");
+        	return false;
+        }
+        
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = conn.prepareStatement("SELECT COALESCE(GET_LOCK(?, ?),0)");
+
+            pstmt.setString(1, name);
+            pstmt.setInt(2, timeoutSeconds);
+            
+            ResultSet rs = pstmt.executeQuery();
+            if (rs != null && rs.first()) {
+            	 if(rs.getInt(1) > 0) {
+            		 return true;
+            	 } else {
+            		 if(s_logger.isDebugEnabled())
+            			 s_logger.debug("GET_LOCK() timed out on lock : " + name);
+            	 }
+            }
+        } catch (SQLException e) {
+            s_logger.error("GET_LOCK() throws exception ", e);
+        } catch (Throwable e) {
+            s_logger.error("GET_LOCK() throws exception ", e);
+        } finally {
+        	if (pstmt != null) {
+        		try {
+        			pstmt.close();
+        		} catch (Throwable e) {
+        			s_logger.error("What the heck? ", e);
+        		}
+        	}
+        }
+        
+        removeConnectionForGlobalLocks(name);
+        try {
+			conn.close();
+		} catch (SQLException e) {
+		}
+        return false;
+    }
+    
+    
+    public static Class<?> getEntityBeanType(GenericDao<?, Long> dao) {
+        return dao.getEntityBeanType();
+    }
+    
+    public static boolean releaseGlobalLock(String name) {
+        Connection conn = getConnectionForGlobalLocks(name, false);
+        if(conn == null) {
+            s_logger.error("Unable to acquire DB connection for global lock system");
+            assert(false);
+        	return false;
+        }
+        
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = conn.prepareStatement("SELECT COALESCE(RELEASE_LOCK(?), 0)");
+            pstmt.setString(1, name);
+            ResultSet rs = pstmt.executeQuery();
+            if(rs != null && rs.first())
+            	return rs.getInt(1) > 0;
+            s_logger.error("RELEASE_LOCK() returns unexpected result : " + rs.getInt(1));
+        } catch (SQLException e) {
+            s_logger.error("RELEASE_LOCK() throws exception ", e);
+        } catch (Throwable e) {
+            s_logger.error("RELEASE_LOCK() throws exception ", e);
+        } finally {
+        	try {
+            	if (pstmt != null) {
+    	        	pstmt.close();
+            	}
+        		conn.close();
+        	} catch(SQLException e) {
+        	}
+        }
+        return false;
+    }
+
+    public static void closeResources(final Connection connection,
+            final Statement statement, final ResultSet resultSet) {
+
+        closeResultSet(resultSet);
+        closeStatement(statement);
+        closeConnection(connection);
+
+    }
+
+    public static void closeResources(final Statement statement, final ResultSet resultSet) {
+
+        closeResources(null, statement, resultSet);
+
+    }
+    
+    public static void closeResultSet(final ResultSet resultSet) {
+
+        try {
+            
+            if (resultSet != null) {
+                resultSet.close();
+            }
+
+        } catch (Exception e) {
+            s_logger.warn("Ignored exception while closing result set.",e);
+        }
+
+    }
+
+    public static void closeStatement(final Statement statement) {
+
+        try {
+
+            if (statement != null) {
+                statement.close();
+            }
+
+        } catch (Exception e) {
+            s_logger.warn("Ignored exception while closing statement.",e);
+        }
+
+    }
+
+    public static void closeConnection(final Connection connection) {
+
+        try {
+
+            if (connection != null) {
+                connection.close();
+            }
+
+        } catch (Exception e) {
+            s_logger.warn("Ignored exception while close connection.",e);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/EcInfo.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/EcInfo.java b/framework/db/src/com/cloud/utils/db/EcInfo.java
new file mode 100644
index 0000000..b33aa57
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/EcInfo.java
@@ -0,0 +1,106 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.CollectionTable;
+import javax.persistence.ElementCollection;
+import javax.persistence.JoinColumn;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class EcInfo {
+    protected String insertSql;
+    protected String selectSql;
+    protected String clearSql;
+    protected Class<?> targetClass;
+    protected Class<?> rawClass;
+
+    public EcInfo(Attribute attr, Attribute idAttr) {
+        attr.attache = this;
+        ElementCollection ec = attr.field.getAnnotation(ElementCollection.class);
+        targetClass = ec.targetClass();
+        Class<?> type = attr.field.getType();
+        if (type.isArray()) {
+            rawClass = null;
+        } else {
+            ParameterizedType pType = (ParameterizedType)attr.field.getGenericType();
+            Type rawType = pType.getRawType();
+            Class<?> rawClazz = (Class<?>)rawType;
+            try {
+                if (!Modifier.isAbstract(rawClazz.getModifiers()) && !rawClazz.isInterface() && rawClazz.getConstructors().length != 0 && rawClazz.getConstructor() != null) {
+                    rawClass = rawClazz;
+                } else if (Set.class == rawClazz) {
+                    rawClass = HashSet.class;
+                } else if (List.class == rawClazz) {
+                    rawClass = ArrayList.class;
+                } else if (Collection.class == Collection.class) {
+                    rawClass = ArrayList.class;
+                } else {
+                    assert (false) : " We don't know how to create this calss " + rawType.toString() + " for " + attr.field.getName();
+                }
+            } catch (NoSuchMethodException e) {
+                throw new CloudRuntimeException("Write your own support for " + rawClazz + " defined by " + attr.field.getName());
+            }
+        }
+
+        CollectionTable ct = attr.field.getAnnotation(CollectionTable.class);
+        assert (ct.name().length() > 0) : "Please sepcify the table for " + attr.field.getName();
+        StringBuilder selectBuf = new StringBuilder("SELECT ");
+        StringBuilder insertBuf = new StringBuilder("INSERT INTO ");
+        StringBuilder clearBuf = new StringBuilder("DELETE FROM ");
+
+        clearBuf.append(ct.name()).append(" WHERE ");
+        selectBuf.append(attr.columnName);
+        selectBuf.append(" FROM ").append(ct.name()).append(", ").append(attr.table);
+        selectBuf.append(" WHERE ");
+
+        insertBuf.append(ct.name()).append("(");
+        StringBuilder valuesBuf = new StringBuilder("SELECT ");
+
+        for (JoinColumn jc : ct.joinColumns()) {
+            selectBuf.append(ct.name()).append(".").append(jc.name()).append("=");
+            if (jc.referencedColumnName().length() == 0) {
+                selectBuf.append(idAttr.table).append(".").append(idAttr.columnName);
+                valuesBuf.append(idAttr.table).append(".").append(idAttr.columnName);
+                clearBuf.append(ct.name()).append(".").append(jc.name()).append("=?");
+            } else {
+                selectBuf.append(attr.table).append(".").append(jc.referencedColumnName());
+                valuesBuf.append(attr.table).append(".").append(jc.referencedColumnName()).append(",");
+            }
+            selectBuf.append(" AND ");
+            insertBuf.append(jc.name()).append(", ");
+            valuesBuf.append(", ");
+        }
+
+        selectSql = selectBuf.append(idAttr.table).append(".").append(idAttr.columnName).append("=?").toString();
+        insertBuf.append(attr.columnName).append(") ");
+        valuesBuf.append("? FROM ").append(attr.table);
+        valuesBuf.append(" WHERE ").append(idAttr.table).append(".").append(idAttr.columnName).append("=?");
+
+        insertSql = insertBuf.append(valuesBuf).toString();
+        clearSql = clearBuf.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/Encrypt.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/Encrypt.java b/framework/db/src/com/cloud/utils/db/Encrypt.java
new file mode 100755
index 0000000..4973458
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/Encrypt.java
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Encrypt is a replacement for the column modification.   
+ */
+@Target(FIELD)
+@Retention(RUNTIME)
+public @interface Encrypt {
+    boolean encrypt() default true;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/Filter.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/Filter.java b/framework/db/src/com/cloud/utils/db/Filter.java
new file mode 100755
index 0000000..c9a4c8a
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/Filter.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Field;
+
+import javax.persistence.Column;
+
+import com.cloud.utils.Pair;
+import com.cloud.utils.ReflectUtil;
+
+/**
+ *  Try to use static initialization to help you in finding incorrect
+ *  field names being passed in early.
+ * 
+ *  Something like the following:
+ *  protected static final Filter s_NameFilter = new Filter(VMInstanceVO, name, true, null, null);
+ * 
+ *  Filter nameFilter = new Filter(s_nameFilter);
+ *
+ */
+public class Filter {
+    Long _offset;
+    Long _limit;
+    String _orderBy;
+    
+    /**
+     * @param clazz the VO object type
+     * @param field name of the field
+     * @param offset
+     * @param limit
+     */
+    public Filter(Class<?> clazz, String field, boolean ascending, Long offset, Long limit) {
+        _offset = offset;
+        _limit = limit;
+        
+        addOrderBy(clazz, field, ascending);
+    }
+    
+    public Filter(long limit) {
+        _orderBy = " ORDER BY RAND() LIMIT " + limit;
+    }
+    
+    /**
+     * Note that this copy constructor does not copy offset and limit.
+     * @param that filter
+     */
+    public Filter(Filter that) {
+        this._orderBy = that._orderBy;
+        this._limit = null;
+        that._limit = null;
+    }
+    
+    public void addOrderBy(Class<?> clazz, String field, boolean ascending) {
+        if (field == null) {
+            return;
+        }
+        Field f;
+        Pair<Class<?>, Field> pair = ReflectUtil.getAnyField(clazz, field);
+        assert(pair != null) : "Can't find field " + field + " in " + clazz.getName();
+        clazz = pair.first();
+        f = pair.second();
+        
+        Column column = f.getAnnotation(Column.class);
+        String name = column != null ? column.name() : field;
+        
+        StringBuilder order = new StringBuilder();
+        if (column.table() == null || column.table().length() == 0) {
+            order.append(DbUtil.getTableName(clazz));
+        } else {
+            order.append(column.table());
+        }
+        order.append(".").append(name).append(ascending ? " ASC " : " DESC ");
+        
+        if (_orderBy == null) {
+            _orderBy = order.insert(0, " ORDER BY ").toString();
+        } else {
+            _orderBy = order.insert(0, _orderBy).toString();
+        }
+    }
+    
+    public String getOrderBy() {
+        return _orderBy;
+    }
+    
+    public void setOffset(Long offset) {
+        _offset = offset;
+    }
+    
+    public Long getOffset() {
+        return _offset;
+    }
+    
+    public Long getLimit() {
+        return _limit;
+    }
+    
+    public void setLimit(Long limit) {
+        _limit = limit;
+    }
+}


[06/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java b/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
new file mode 100644
index 0000000..40fcbbf
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Method;
+
+import com.cloud.utils.component.ComponentMethodInterceptor;
+
+public class TransactionContextBuilder implements ComponentMethodInterceptor {
+	public TransactionContextBuilder() {
+	}
+	
+	@Override
+	public boolean needToIntercept(Method method) {
+        DB db = method.getAnnotation(DB.class);
+        if (db != null) {
+            return true;
+        }
+        
+        Class<?> clazz = method.getDeclaringClass();
+        
+        do {
+            db = clazz.getAnnotation(DB.class);
+            if (db != null) {
+                return true;
+            }
+            clazz = clazz.getSuperclass();
+        } while (clazz != Object.class && clazz != null);
+        
+        return false;
+    }
+
+	@Override
+    public Object interceptStart(Method method, Object target) {
+    	return Transaction.open(method.getName());
+    }
+    
+	@Override
+    public void interceptComplete(Method method, Object target, Object objReturnedInInterceptStart) {
+    	Transaction txn = (Transaction)objReturnedInInterceptStart;
+    	if(txn != null)
+    		txn.close();
+    }
+    
+	@Override
+    public void interceptException(Method method, Object target, Object objReturnedInInterceptStart) {
+    	Transaction txn = (Transaction)objReturnedInInterceptStart;
+    	if(txn != null)
+    		txn.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/TransactionMBean.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionMBean.java b/framework/db/src/com/cloud/utils/db/TransactionMBean.java
new file mode 100644
index 0000000..b868360
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/TransactionMBean.java
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.util.List;
+import java.util.Map;
+
+public interface TransactionMBean {
+    int getTransactionCount();
+    
+    int[] getActiveTransactionCount();
+    
+    List<Map<String, String>> getTransactions();
+    
+    List<Map<String, String>> getActiveTransactions();
+    
+    List<Map<String, String>> getTransactionsWithDatabaseConnection();
+    
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java b/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java
new file mode 100644
index 0000000..d51a9bd
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.management.StandardMBean;
+
+import com.cloud.utils.db.Transaction.StackElement;
+
+public class TransactionMBeanImpl extends StandardMBean implements TransactionMBean {
+    
+    Map<Long, Transaction> _txns = new ConcurrentHashMap<Long, Transaction>();
+    
+    public TransactionMBeanImpl() {
+        super(TransactionMBean.class, false);
+    }
+    
+    public void addTransaction(Transaction txn) {
+        _txns.put(txn.getId(), txn);
+    }
+    
+    public void removeTransaction(Transaction txn) {
+        _txns.remove(txn.getId());
+    }
+    
+    @Override
+    public int getTransactionCount() {
+        return _txns.size();
+    }
+    
+    @Override
+    public int[] getActiveTransactionCount() {
+        int[] count = new int[2];
+        count[0] = 0;
+        count[1] = 0;
+        for (Transaction txn : _txns.values()) {
+            if (txn.getStack().size() > 0) {
+                count[0]++;
+            }
+            if (txn.getCurrentConnection() != null) {
+                count[1]++;
+            }
+        }
+        return count;
+    }
+    
+    @Override
+    public List<Map<String, String>> getTransactions() {
+        ArrayList<Map<String, String>> txns = new ArrayList<Map<String, String>>();
+        for (Transaction info : _txns.values()) {
+            txns.add(toMap(info));
+        }
+        return txns;
+    }
+    
+    @Override
+    public List<Map<String, String>> getActiveTransactions() {
+        ArrayList<Map<String, String>> txns = new ArrayList<Map<String, String>>();
+        for (Transaction txn : _txns.values()) {
+            if (txn.getStack().size() > 0 || txn.getCurrentConnection() != null) {
+                txns.add(toMap(txn));
+            }
+        }
+        return txns;
+    }
+    
+    protected Map<String, String> toMap(Transaction txn) {
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("name", txn.getName());
+        map.put("id", Long.toString(txn.getId()));
+        map.put("creator", txn.getCreator());
+        Connection conn = txn.getCurrentConnection();
+        map.put("db", conn != null ? Integer.toString(System.identityHashCode(conn)) : "none");
+        StringBuilder buff = new StringBuilder();
+        for (StackElement element : txn.getStack()) {
+            buff.append(element.toString()).append(",");
+        }
+        map.put("stack", buff.toString());
+        
+        return map;
+    }
+
+    @Override
+    public List<Map<String, String>> getTransactionsWithDatabaseConnection() {
+        ArrayList<Map<String, String>> txns = new ArrayList<Map<String, String>>();
+        for (Transaction txn : _txns.values()) {
+            if (txn.getCurrentConnection() != null) {
+                txns.add(toMap(txn));
+            }
+        }
+        return txns;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/UpdateBuilder.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/UpdateBuilder.java b/framework/db/src/com/cloud/utils/db/UpdateBuilder.java
new file mode 100755
index 0000000..c13aa51
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/UpdateBuilder.java
@@ -0,0 +1,147 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class UpdateBuilder implements MethodInterceptor {
+    protected Map<String, Ternary<Attribute, Boolean, Object>> _changes;
+    protected HashMap<Attribute, Object> _collectionChanges;
+    protected GenericDaoBase<?, ?> _dao;
+    
+    protected UpdateBuilder(GenericDaoBase<?, ?> dao) {
+        _dao = dao;
+        _changes = new HashMap<String, Ternary<Attribute, Boolean, Object>>();
+    }
+    
+    @Override
+    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
+        String name = method.getName();
+        if (name.startsWith("set")) {
+        	String field = methodToField(name, 3);
+            makeChange(field, args[0]);
+        } else if (name.startsWith("incr")) {
+        	makeIncrChange(name, args);
+        } else if (name.startsWith("decr")) {
+        	makeDecrChange(name, args);
+        }
+        return methodProxy.invokeSuper(object, args);
+    }
+    
+    private final String methodToField(String method, int start) {
+    	char[] chs = method.toCharArray();
+    	chs[start] = Character.toLowerCase(chs[start]);
+    	return new String(chs, start, chs.length - start);
+    }
+    
+    protected Attribute makeChange(String field, Object value) {
+        Attribute attr = _dao._allAttributes.get(field);
+        
+        assert (attr == null || attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field;
+        if (attr != null) {
+            if (attr.attache == null) {
+                _changes.put(field, new Ternary<Attribute, Boolean, Object>(attr, null, value));
+            } else {
+                if (_collectionChanges == null) {
+                    _collectionChanges = new HashMap<Attribute, Object>();
+                }
+                _collectionChanges.put(attr, value);
+            }
+        }
+        return attr;
+    }
+    
+    protected void makeIncrChange(String method, Object[] args) {
+    	String field = methodToField(method, 4);
+    	Attribute attr = _dao._allAttributes.get(field);
+        assert (attr != null && attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field;
+    	incr(attr, args == null || args.length == 0 ? 1 : args[0]);
+    }
+    
+    protected void makeDecrChange(String method, Object[] args) {
+    	String field = methodToField(method, 4);
+    	Attribute attr = _dao._allAttributes.get(field);
+        assert (attr != null && attr.isUpdatable()) : "Updating an attribute that's not updatable: " + field;
+    	decr(attr, args == null || args.length == 0 ? 1 : args[0]);
+    }
+    
+    public void set(Object entity, String name, Object value) {
+    	Attribute attr = makeChange(name, value);
+
+    	set(entity, attr, value);
+    }
+    
+    public void set(Object entity, Attribute attr, Object value) {
+        _changes.put(attr.field.getName(), new Ternary<Attribute, Boolean, Object>(attr, null, value));
+        try {
+			attr.field.set(entity, value);
+		} catch (IllegalArgumentException e) {
+			throw new CloudRuntimeException("Unable to update " + attr.field.getName() + " with " + value, e);
+		} catch (IllegalAccessException e) {
+			throw new CloudRuntimeException("Unable to update " + attr.field.getName() + " with " + value, e);
+		}
+    }
+    
+    public void incr(Attribute attr, Object value) {
+        _changes.put(attr.field.getName(), new Ternary<Attribute, Boolean, Object>(attr, true, value));
+    }
+    
+    public void decr(Attribute attr, Object value) {
+        _changes.put(attr.field.getName(), new Ternary<Attribute, Boolean, Object>(attr, false, value));
+    }
+    
+    public boolean hasChanges() {
+        return (_changes.size() + (_collectionChanges != null ? _collectionChanges.size() : 0)) != 0;
+    }
+    
+    public boolean has(String name) {
+        return _changes.containsKey(name);
+    }
+    
+    public Map<Attribute, Object> getCollectionChanges() {
+        return _collectionChanges;
+    }
+    
+    public void clear() {
+        _changes.clear();
+        if (_collectionChanges != null) {
+            _collectionChanges.clear();
+            _collectionChanges = null;
+        }
+    }
+    
+    public StringBuilder toSql(String tables) {
+    	if (_changes.isEmpty()) {
+    		return null;
+    	}
+    	
+    	return SqlGenerator.buildMysqlUpdateSql(tables, _changes.values());
+    }
+    
+    public Collection<Ternary<Attribute, Boolean, Object>> getChanges() {
+    	return _changes.values();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/UpdateFilter.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/UpdateFilter.java b/framework/db/src/com/cloud/utils/db/UpdateFilter.java
new file mode 100644
index 0000000..37b35b1
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/UpdateFilter.java
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.CallbackFilter;
+
+public class UpdateFilter implements CallbackFilter {
+    @Override
+    public int accept(Method method) {
+        String name = method.getName();
+        return (name.startsWith("set") || name.startsWith("incr") || name.startsWith("decr")) ? 1 : 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/DbAnnotatedBase.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/DbAnnotatedBase.java b/framework/db/test/com/cloud/utils/db/DbAnnotatedBase.java
new file mode 100644
index 0000000..f87b20f
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/DbAnnotatedBase.java
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import junit.framework.Assert;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+@Component
+@DB
+public class DbAnnotatedBase {
+    private static final Logger s_logger = Logger.getLogger(DbAnnotatedBase.class);
+
+    @Inject DummyComponent _dummy;
+    
+    @PostConstruct
+    public void initTest() {
+    	Assert.assertTrue(true);
+    }
+    
+    public void MethodWithClassDbAnnotated() {
+    	s_logger.info("called");
+    	_dummy.sayHello();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java b/framework/db/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java
new file mode 100644
index 0000000..38e045c
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java
@@ -0,0 +1,27 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DbAnnotatedBaseDerived extends DbAnnotatedBase {
+
+	@DB
+	public void DbAnnotatedMethod() {
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/DbTestDao.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/DbTestDao.java b/framework/db/test/com/cloud/utils/db/DbTestDao.java
new file mode 100644
index 0000000..9530b3b
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/DbTestDao.java
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.sql.PreparedStatement;
+import java.util.Date;
+import java.util.TimeZone;
+
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class DbTestDao extends GenericDaoBase<DbTestVO, Long> implements GenericDao<DbTestVO, Long> {
+    protected DbTestDao() {
+    }
+
+    @DB
+    public void create(int fldInt, long fldLong, String fldString) {
+        Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+            pstmt = txn
+                    .prepareAutoCloseStatement("insert into cloud.test(fld_int, fld_long, fld_string) values(?, ?, ?)");
+            pstmt.setInt(1, fldInt);
+            pstmt.setLong(2, fldLong);
+            pstmt.setString(3, fldString);
+
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (Exception e) {
+            throw new CloudRuntimeException("Problem with creating a record in test table", e);
+        }
+    }
+
+    @DB
+    public void update(int fldInt, long fldLong, String fldString) {
+        Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement("update cloud.test set fld_int=?, fld_long=? where fld_string=?");
+            pstmt.setInt(1, fldInt);
+            pstmt.setLong(2, fldLong);
+            pstmt.setString(3, fldString);
+
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (Exception e) {
+            throw new CloudRuntimeException("Problem with creating a record in test table", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/DbTestUtils.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/DbTestUtils.java b/framework/db/test/com/cloud/utils/db/DbTestUtils.java
new file mode 100644
index 0000000..11ae1aa
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/DbTestUtils.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import com.cloud.utils.PropertiesUtil;
+
+public class DbTestUtils {
+    
+    public static void executeScript(String file, boolean autoCommit, boolean stopOnError) {
+        File cleanScript = PropertiesUtil.findConfigFile(file);
+        if (cleanScript == null) {
+            throw new RuntimeException("Unable to clean the database because I can't find " + file);
+        }
+        
+        Connection conn = Transaction.getStandaloneConnection();
+        
+        ScriptRunner runner = new ScriptRunner(conn, autoCommit, stopOnError);
+        FileReader reader;
+        try {
+            reader = new FileReader(cleanScript);
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("Unable to read " + file, e);
+        } 
+        try {
+            runner.runScript(reader);
+        } catch (IOException e) {
+            throw new RuntimeException("Unable to read " + file, e);
+        } catch (SQLException e) {
+            throw new RuntimeException("Unable to execute " + file, e);
+        }
+        
+        try {
+            conn.close();
+        } catch (SQLException e) {
+            throw new RuntimeException("Unable to close DB connection", e);
+        }
+    }
+
+    public static void executeUsageScript(String file, boolean autoCommit, boolean stopOnError) {
+        File cleanScript = PropertiesUtil.findConfigFile(file);
+        if (cleanScript == null) {
+            throw new RuntimeException("Unable to clean the database because I can't find " + file);
+        }
+        
+        Connection conn = Transaction.getStandaloneUsageConnection();
+        
+        ScriptRunner runner = new ScriptRunner(conn, autoCommit, stopOnError);
+        FileReader reader;
+        try {
+            reader = new FileReader(cleanScript);
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("Unable to read " + file, e);
+        } 
+        try {
+            runner.runScript(reader);
+        } catch (IOException e) {
+            throw new RuntimeException("Unable to read " + file, e);
+        } catch (SQLException e) {
+            throw new RuntimeException("Unable to execute " + file, e);
+        }
+        
+        try {
+            conn.close();
+        } catch (SQLException e) {
+            throw new RuntimeException("Unable to close DB connection", e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/DbTestVO.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/DbTestVO.java b/framework/db/test/com/cloud/utils/db/DbTestVO.java
new file mode 100644
index 0000000..5285bfe
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/DbTestVO.java
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "test")
+public class DbTestVO {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    long id;
+
+    @Column(name = "fld_int")
+    int fieldInt;
+
+    @Column(name = "fld_long")
+    Long fieldLong;
+
+    @Column(name = "fld_string")
+    String fieldString;
+
+    public String getFieldString() {
+        return fieldString;
+    }
+
+    public int getFieldInt() {
+        return fieldInt;
+    }
+
+    public long getFieldLong() {
+        return fieldLong;
+    }
+
+    public DbTestVO() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/DummyComponent.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/DummyComponent.java b/framework/db/test/com/cloud/utils/db/DummyComponent.java
new file mode 100644
index 0000000..2922630
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/DummyComponent.java
@@ -0,0 +1,27 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DummyComponent {
+
+	public void sayHello() {
+		System.out.println("Hello, world");
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/ElementCollectionTest.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/ElementCollectionTest.java b/framework/db/test/com/cloud/utils/db/ElementCollectionTest.java
new file mode 100644
index 0000000..b860af5
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/ElementCollectionTest.java
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+
+
+public class ElementCollectionTest extends TestCase {
+    static final Logger s_logger = Logger.getLogger(ElementCollectionTest.class);
+    ArrayList<String> ar = null;
+    List<String> lst = null;
+    Collection<String> coll = null;
+    String[] array = null;
+
+    public void testArrayList() throws Exception {
+        Field[] fields = this.getClass().getDeclaredFields();
+        for (Field field : fields) {
+            if (Modifier.isStatic(field.getModifiers())) {
+                continue;
+            }
+            Class<?> type1 = field.getType();
+            Object collection = null;
+            if (!type1.isArray()) {
+                ParameterizedType type = (ParameterizedType)field.getGenericType();
+                Type rawType = type.getRawType();
+                Class<?> rawClazz = (Class<?>)rawType;
+                if (!Modifier.isAbstract(rawClazz.getModifiers()) && !rawClazz.isInterface() && rawClazz.getConstructors().length != 0 && rawClazz.getConstructor() != null) {
+                    collection = rawClazz.newInstance();
+                }
+
+                if (collection == null) {
+                    if (Collection.class.isAssignableFrom(rawClazz)) {
+                        collection = new ArrayList();
+                    } else if (Set.class.isAssignableFrom(rawClazz)) {
+                        collection = new HashSet();
+                    }
+                }
+            } else {
+                collection = Array.newInstance(String.class, 1);
+            }
+            field.set(this, collection);
+            assert (field.get(this) != null);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/GlobalLockTest.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/GlobalLockTest.java b/framework/db/test/com/cloud/utils/db/GlobalLockTest.java
new file mode 100644
index 0000000..8d6ff41
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/GlobalLockTest.java
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import org.apache.log4j.Logger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.cloud.utils.Profiler;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations="classpath:/testContext.xml")
+public class GlobalLockTest {
+    public static final Logger s_logger = Logger.getLogger(GlobalLockTest.class);
+    private final static GlobalLock _workLock = GlobalLock.getInternLock("SecurityGroupWork");
+    public static class Worker implements Runnable {
+        int id = 0;
+        int timeoutSeconds = 10;
+        int jobDuration = 2;
+        public Worker(int id, int timeout, int duration) {
+            this.id = id;
+            timeoutSeconds = timeout;
+            jobDuration = duration;
+        }
+        @Override
+        public void run() {
+            boolean locked = false;
+            try {
+                Profiler p = new Profiler();
+                p.start();
+                locked = _workLock.lock(timeoutSeconds);
+                p.stop();
+                System.out.println("Thread " + id + " waited " + p.getDuration() + " ms, locked=" + locked);
+                if (locked) {
+                    Thread.sleep(jobDuration*1000);
+                }
+            } catch (InterruptedException e) {
+            } finally {
+                if (locked) {
+                    boolean unlocked = _workLock.unlock();
+                    System.out.println("Thread " + id + "  unlocked=" + unlocked);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testTimeout() {
+        Thread [] pool = new Thread[50];
+        for (int i=0; i < pool.length; i++) {
+            pool[i] = new Thread(new Worker(i, 5, 3));
+        }
+        for (int i=0; i < pool.length; i++) {
+            pool[i].start();
+        }
+        for (int i=0; i < pool.length; i++) {
+            try {
+                pool[i].join();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/Merovingian2Test.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/Merovingian2Test.java b/framework/db/test/com/cloud/utils/db/Merovingian2Test.java
new file mode 100644
index 0000000..8246faa
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/Merovingian2Test.java
@@ -0,0 +1,77 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class Merovingian2Test extends TestCase {
+    static final Logger s_logger = Logger.getLogger(Merovingian2Test.class);
+    Merovingian2 _lockMaster = Merovingian2.createLockMaster(1234);
+    
+    @Override @Before
+    protected void setUp() throws Exception {
+        _lockMaster.cleanupThisServer();
+    }
+    
+    @Override @After
+    protected void tearDown() throws Exception {
+        _lockMaster.cleanupThisServer();
+    }
+
+    @Test
+    public void testLockAndRelease() {
+        
+        s_logger.info("Testing first acquire");
+        boolean result = _lockMaster.acquire("first"+1234, 5);
+        Assert.assertTrue(result);
+        
+        s_logger.info("Testing acquire of different lock");
+        result = _lockMaster.acquire("second"+1234, 5);
+        Assert.assertTrue(result);
+        
+        s_logger.info("Testing reacquire of the same lock");
+        result = _lockMaster.acquire("first"+1234, 5);
+        Assert.assertTrue(result);
+        
+        int count = _lockMaster.owns("first"+1234);
+        Assert.assertEquals(count, 2);
+        
+        count = _lockMaster.owns("second"+1234);
+        Assert.assertEquals(count, 1);
+        
+        s_logger.info("Testing release of the first lock");
+        result = _lockMaster.release("first"+1234);
+        Assert.assertTrue(result);
+        
+        count = _lockMaster.owns("first"+1234);
+        Assert.assertEquals(count, 1);
+        
+        s_logger.info("Testing release of the second lock");
+        result = _lockMaster.release("second"+1234);
+        Assert.assertTrue(result);
+        
+        result = _lockMaster.release("first"+1234);
+        Assert.assertTrue(result);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/TransactionContextBuilderTest.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/TransactionContextBuilderTest.java b/framework/db/test/com/cloud/utils/db/TransactionContextBuilderTest.java
new file mode 100644
index 0000000..33e7aa0
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/TransactionContextBuilderTest.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.cloud.utils.component.ComponentContext;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations="classpath:/com/cloud/utils/db/transactioncontextBuilderTest.xml")
+public class TransactionContextBuilderTest {
+
+	@Inject
+	DbAnnotatedBaseDerived _derived; 
+	
+	DbAnnotatedBase _base;
+	
+	@Inject
+	List<DbAnnotatedBase> _list;
+	
+	@Test
+	public void test() {
+		// _derived.DbAnnotatedMethod();
+		// _base.MethodWithClassDbAnnotated();
+		
+		// test @DB injection on dynamically constructed objects
+		DbAnnotatedBase base = ComponentContext.inject(new DbAnnotatedBase());
+		base.MethodWithClassDbAnnotated();
+
+/*		
+		Map<String, DbAnnotatedBase> components = ComponentContext.getApplicationContext().getBeansOfType(DbAnnotatedBase.class);
+		for(Map.Entry<String, DbAnnotatedBase> entry : components.entrySet()) {
+			System.out.println(entry.getKey());
+			entry.getValue().MethodWithClassDbAnnotated();
+		}
+*/
+		for(DbAnnotatedBase entry : _list) {
+			entry.MethodWithClassDbAnnotated();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/test/com/cloud/utils/db/TransactionTest.java
----------------------------------------------------------------------
diff --git a/framework/db/test/com/cloud/utils/db/TransactionTest.java b/framework/db/test/com/cloud/utils/db/TransactionTest.java
new file mode 100644
index 0000000..101a533
--- /dev/null
+++ b/framework/db/test/com/cloud/utils/db/TransactionTest.java
@@ -0,0 +1,214 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+/**
+ * A test fixture to test APIs or bugs found for Transaction class. This test fixture will do one time setup before
+ * all its testcases to set up a test db table, and then tear down these test db artifacts after all testcases are run.
+ *
+ */
+public class TransactionTest {
+
+    @BeforeClass
+    public static void oneTimeSetup() {
+        Connection conn = null;
+        PreparedStatement pstmt = null;
+        try {
+            conn = Transaction.getStandaloneConnection();
+
+            pstmt = conn.prepareStatement("CREATE TABLE `cloud`.`test` ("
+                    + "`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT," + "`fld_int` int unsigned,"
+                    + "`fld_long` bigint unsigned," + "`fld_string` varchar(255)," + "PRIMARY KEY (`id`)"
+                    + ") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+
+            pstmt.execute();
+
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Problem with sql", e);
+        } finally {
+            if (pstmt != null) {
+                try {
+                    pstmt.close();
+                } catch (SQLException e) {
+                }
+            }
+            if (conn != null) {
+                try {
+                    conn.close();
+                } catch (SQLException e) {
+                }
+            }
+        }
+    }
+
+    @Test
+    /**
+     * When a transaction is set to use user-managed db connection, for each following db statement, we should see
+     * that the same db connection is reused rather than acquiring a new one each time in typical transaction model.
+     */
+    public void testUserManagedConnection() {
+        DbTestDao testDao = ComponentContext.inject(DbTestDao.class);
+        Transaction txn = Transaction.open("SingleConnectionThread");
+        Connection conn = null;
+        try {
+            conn = Transaction.getStandaloneConnectionWithException();
+            txn.transitToUserManagedConnection(conn);
+            // try two SQLs to make sure that they are using the same connection
+            // acquired above.
+            testDao.create(1, 1, "Record 1");
+            Connection checkConn = Transaction.currentTxn().getConnection();
+            if (checkConn != conn) {
+                Assert.fail("A new db connection is acquired instead of using old one after create sql");
+            }
+            testDao.update(2, 2, "Record 1");
+            Connection checkConn2 = Transaction.currentTxn().getConnection();
+            if (checkConn2 != conn) {
+                Assert.fail("A new db connection is acquired instead of using old one after update sql");
+            }
+        } catch (SQLException e) {
+            Assert.fail(e.getMessage());
+        } finally {
+            txn.transitToAutoManagedConnection(Transaction.CLOUD_DB);
+            txn.close();
+
+            if (conn != null) {
+                try {
+                    conn.close();
+                } catch (SQLException e) {
+                    throw new CloudRuntimeException("Problem with close db connection", e);
+                }
+            }
+        }
+    }
+
+    @Test
+    /**
+     * This test is simulating ClusterHeartBeat process, where the same transaction and db connection is reused.
+     */
+    public void testTransactionReuse() {
+        DbTestDao testDao = ComponentContext.inject(DbTestDao.class);
+        // acquire a db connection and keep it
+        Connection conn = null;
+        try {
+            conn = Transaction.getStandaloneConnectionWithException();
+        } catch (SQLException ex) {
+            throw new CloudRuntimeException("Problem with getting db connection", ex);
+        }
+
+        // start heartbeat loop, make sure that each loop still use the same
+        // connection
+        Transaction txn = null;
+        for (int i = 0; i < 3; i++) {
+            txn = Transaction.open("HeartbeatSimulator");
+            try {
+
+                txn.transitToUserManagedConnection(conn);
+                testDao.create(i, i, "Record " + i);
+                Connection checkConn = Transaction.currentTxn().getConnection();
+                if (checkConn != conn) {
+                    Assert.fail("A new db connection is acquired instead of using old one in loop " + i);
+                }
+            } catch (SQLException e) {
+                Assert.fail(e.getMessage());
+            } finally {
+                txn.transitToAutoManagedConnection(Transaction.CLOUD_DB);
+                txn.close();
+            }
+        }
+        // close the connection once we are done since we are managing db
+        // connection ourselves.
+        if (conn != null) {
+            try {
+                conn.close();
+            } catch (SQLException e) {
+                throw new CloudRuntimeException("Problem with close db connection", e);
+            }
+        }
+    }
+
+    @After
+    /**
+     * Delete all records after each test, but table is still kept
+     */
+    public void tearDown() {
+        Connection conn = null;
+        PreparedStatement pstmt = null;
+        try {
+            conn = Transaction.getStandaloneConnection();
+
+            pstmt = conn.prepareStatement("truncate table `cloud`.`test`");
+            pstmt.execute();
+
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Problem with sql", e);
+        } finally {
+            if (pstmt != null) {
+                try {
+                    pstmt.close();
+                } catch (SQLException e) {
+                }
+            }
+            if (conn != null) {
+                try {
+                    conn.close();
+                } catch (SQLException e) {
+                }
+            }
+        }
+    }
+
+    @AfterClass
+    public static void oneTimeTearDown() {
+        Connection conn = null;
+        PreparedStatement pstmt = null;
+        try {
+            conn = Transaction.getStandaloneConnection();
+
+            pstmt = conn.prepareStatement("DROP TABLE IF EXISTS `cloud`.`test`");
+            pstmt.execute();
+
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Problem with sql", e);
+        } finally {
+            if (pstmt != null) {
+                try {
+                    pstmt.close();
+                } catch (SQLException e) {
+                }
+            }
+            if (conn != null) {
+                try {
+                    conn.close();
+                } catch (SQLException e) {
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/plugins/hypervisors/vmware/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml
index 755244f..ad76411 100644
--- a/plugins/hypervisors/vmware/pom.xml
+++ b/plugins/hypervisors/vmware/pom.xml
@@ -64,15 +64,5 @@
       <artifactId>wsdl4j</artifactId>
       <version>1.4</version>
     </dependency>
-      <dependency>
-          <groupId>junit</groupId>
-          <artifactId>junit</artifactId>
-          <version>4.10</version>
-      </dependency>
-      <dependency>
-          <groupId>org.mockito</groupId>
-          <artifactId>mockito-all</artifactId>
-          <version>1.9.5</version>
-      </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index ff1e9c9..e2f767a 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -77,7 +77,7 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
+      <artifactId>cloud-api</artifactId>
       <version>${project.version}</version>
       <type>test-jar</type>
       <scope>test</scope>      

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index 484d603..20bcece 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -92,7 +92,7 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
+      <artifactId>cloud-api</artifactId>
       <version>${project.version}</version>
       <type>test-jar</type>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index 223c6b3..65e2113 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -352,7 +352,7 @@ public class ApiDispatcher {
         for (Class<?> entity : entities) {
             // For backward compatibility, we search within removed entities and let service layer deal
             // with removed ones, return empty response or error
-            Object objVO = s_instance._entityMgr.findByUuidIncludingRemoved(entity, uuid);
+            Object objVO = s_instance._entityMgr.findByUuid(entity, uuid);
             if (objVO == null) {
                 continue;
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index f7b740b..c1ae7d0 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -31,6 +31,9 @@ import java.util.TimeZone;
 
 import javax.inject.Inject;
 
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.affinity.AffinityGroup;
@@ -70,6 +73,7 @@ import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
 import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
 import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.InstanceGroupResponse;
 import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
 import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
@@ -86,7 +90,6 @@ import org.apache.cloudstack.api.response.NetworkOfferingResponse;
 import org.apache.cloudstack.api.response.NetworkResponse;
 import org.apache.cloudstack.api.response.NicResponse;
 import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.api.response.ImageStoreResponse;
 import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
 import org.apache.cloudstack.api.response.PodResponse;
 import org.apache.cloudstack.api.response.PortableIpRangeResponse;
@@ -144,9 +147,6 @@ import org.apache.cloudstack.usage.Usage;
 import org.apache.cloudstack.usage.UsageService;
 import org.apache.cloudstack.usage.UsageTypes;
 
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
 import com.cloud.api.query.ViewResponseHelper;
 import com.cloud.api.query.vo.AccountJoinVO;
 import com.cloud.api.query.vo.AsyncJobJoinVO;
@@ -301,9 +301,9 @@ public class ApiResponseHelper implements ResponseGenerator {
     public final Logger s_logger = Logger.getLogger(ApiResponseHelper.class);
     private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##");
     @Inject
-    private EntityManager _entityMgr = null;
+    private final EntityManager _entityMgr = null;
     @Inject
-    private UsageService _usageSvc = null;
+    private final UsageService _usageSvc = null;
     @Inject NetworkModel _ntwkModel;
 
     @Override
@@ -831,7 +831,7 @@ public class ApiResponseHelper implements ResponseGenerator {
                 capacityResponse.setCapacityType(capacity.getCapacityType());
                 capacityResponse.setCapacityUsed(capacity.getUsedCapacity());
                 if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) {
-                    capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity())));
+                    capacityResponse.setCapacityTotal(new Long((capacity.getTotalCapacity())));
                 } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
                     List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null);
                     capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
@@ -1409,7 +1409,7 @@ public class ApiResponseHelper implements ResponseGenerator {
             templateResponse.setOsTypeName("");
         }
 
-        final Account account = ApiDBUtils.findAccountByIdIncludingRemoved(iso.getAccountId());
+        final Account account = ApiDBUtils.findAccountById(iso.getAccountId());
         populateAccount(templateResponse, account.getId());
         populateDomain(templateResponse, account.getDomainId());
 
@@ -1466,7 +1466,7 @@ public class ApiResponseHelper implements ResponseGenerator {
             isoResponse.setOsTypeId("-1");
             isoResponse.setOsTypeName("");
         }
-        Account account = ApiDBUtils.findAccountByIdIncludingRemoved(iso.getAccountId());
+        Account account = ApiDBUtils.findAccountById(iso.getAccountId());
         populateAccount(isoResponse, account.getId());
         populateDomain(isoResponse, account.getDomainId());
         boolean isAdmin = false;
@@ -1521,7 +1521,7 @@ public class ApiResponseHelper implements ResponseGenerator {
             isoResponse.setOsTypeName("");
         }
 
-        Account account = ApiDBUtils.findAccountByIdIncludingRemoved(iso.getAccountId());
+        Account account = ApiDBUtils.findAccountById(iso.getAccountId());
         populateAccount(isoResponse, account.getId());
         populateDomain(isoResponse, account.getDomainId());
 
@@ -1578,7 +1578,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         isoResponses.add(isoResponse);
         return isoResponses;
     }
-*/
+    */
 
     @Override
     public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) {
@@ -1909,7 +1909,7 @@ public class ApiResponseHelper implements ResponseGenerator {
                 regularAccounts.add(accountName);
             } else {
                 // convert account to projectIds
-                Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId());
+                Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
 
                 if (project.getUuid() != null && !project.getUuid().isEmpty())
                     projectIds.add(project.getUuid());
@@ -2211,7 +2211,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         }
 
         // populate network offering information
-        NetworkOffering networkOffering = (NetworkOffering) ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
+        NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
         if (networkOffering != null) {
             response.setNetworkOfferingId(networkOffering.getUuid());
             response.setNetworkOfferingName(networkOffering.getName());
@@ -2455,11 +2455,11 @@ public class ApiResponseHelper implements ResponseGenerator {
     // ControlledEntity id to uuid conversion are all done.
     // currently code is scattered in
     private void populateOwner(ControlledEntityResponse response, ControlledEntity object) {
-        Account account = ApiDBUtils.findAccountByIdIncludingRemoved(object.getAccountId());
+        Account account = ApiDBUtils.findAccountById(object.getAccountId());
 
         if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
             // find the project
-            Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId());
+            Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
             response.setProjectId(project.getUuid());
             response.setProjectName(project.getName());
         } else {
@@ -2485,10 +2485,10 @@ public class ApiResponseHelper implements ResponseGenerator {
     }
 
     private void populateAccount(ControlledEntityResponse response, long accountId) {
-        Account account = ApiDBUtils.findAccountByIdIncludingRemoved(accountId);
+        Account account = ApiDBUtils.findAccountById(accountId);
         if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
             // find the project
-            Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId());
+            Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
             response.setProjectId(project.getUuid());
             response.setProjectName(project.getName());
             response.setAccountName(account.getAccountName());
@@ -3273,10 +3273,10 @@ public class ApiResponseHelper implements ResponseGenerator {
 	public UsageRecordResponse createUsageResponse(Usage usageRecord) {
 		UsageRecordResponse usageRecResponse = new UsageRecordResponse();
 
-		Account account = ApiDBUtils.findAccountByIdIncludingRemoved(usageRecord.getAccountId());
+        Account account = ApiDBUtils.findAccountById(usageRecord.getAccountId());
 		if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
 			//find the project
-			Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId());
+            Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
 			usageRecResponse.setProjectId(project.getUuid());
 			usageRecResponse.setProjectName(project.getName());
 		} else {
@@ -3299,7 +3299,7 @@ public class ApiResponseHelper implements ResponseGenerator {
 		usageRecResponse.setUsage(usageRecord.getUsageDisplay());
 		usageRecResponse.setUsageType(usageRecord.getUsageType());
 		if (usageRecord.getVmInstanceId() != null) {
-			VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId());
+            VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getVmInstanceId());
 			usageRecResponse.setVirtualMachineId(vm.getUuid());
 		}
 		usageRecResponse.setVmName(usageRecord.getVmName());
@@ -3311,11 +3311,11 @@ public class ApiResponseHelper implements ResponseGenerator {
 		}
 
 		if(usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM){
-			ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId().toString());
+            ServiceOfferingVO svcOffering = _entityMgr.findById(ServiceOfferingVO.class, usageRecord.getOfferingId().toString());
 			//Service Offering Id
 			usageRecResponse.setOfferingId(svcOffering.getUuid());
 			//VM Instance ID
-			VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
+            VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getUsageId().toString());
 			usageRecResponse.setUsageId(vm.getUuid());
 			//Hypervisor Type
 			usageRecResponse.setType(usageRecord.getType());
@@ -3326,7 +3326,7 @@ public class ApiResponseHelper implements ResponseGenerator {
 			//isSystem
 			usageRecResponse.setSystem((usageRecord.getSize() == 1)?true:false);
 			//IP Address ID
-			IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString());
+            IPAddressVO ip = _entityMgr.findById(IPAddressVO.class, usageRecord.getUsageId().toString());
 			usageRecResponse.setUsageId(ip.getUuid());
 
 		} else if(usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED){
@@ -3334,15 +3334,15 @@ public class ApiResponseHelper implements ResponseGenerator {
 			usageRecResponse.setType(usageRecord.getType());
 			if(usageRecord.getType().equals("DomainRouter")){
 				//Domain Router Id
-				VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
+                VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getUsageId().toString());
 				usageRecResponse.setUsageId(vm.getUuid());
 			} else {
 				//External Device Host Id
-				HostVO host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId().toString());
+                HostVO host = _entityMgr.findById(HostVO.class, usageRecord.getUsageId().toString());
 				usageRecResponse.setUsageId(host.getUuid());
 			}
 			//Network ID
-			NetworkVO network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString());
+            NetworkVO network = _entityMgr.findById(NetworkVO.class, usageRecord.getNetworkId().toString());
 			usageRecResponse.setNetworkId(network.getUuid());
 
         } else if(usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE ||
@@ -3350,27 +3350,27 @@ public class ApiResponseHelper implements ResponseGenerator {
             //Device Type
             usageRecResponse.setType(usageRecord.getType());
             //VM Instance Id
-            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
+            VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
             usageRecResponse.setVirtualMachineId(vm.getUuid());
             //Volume ID
-            VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
+            VolumeVO volume = _entityMgr.findById(VolumeVO.class, usageRecord.getUsageId().toString());
             usageRecResponse.setUsageId(volume.getUuid());
 
 		} else if(usageRecord.getUsageType() == UsageTypes.VOLUME){
 			//Volume ID
-			VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
+            VolumeVO volume = _entityMgr.findById(VolumeVO.class, usageRecord.getUsageId().toString());
 			usageRecResponse.setUsageId(volume.getUuid());
 			//Volume Size
 			usageRecResponse.setSize(usageRecord.getSize());
 			//Disk Offering Id
 			if(usageRecord.getOfferingId() != null){
-				DiskOfferingVO diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString());
+                DiskOfferingVO diskOff = _entityMgr.findById(DiskOfferingVO.class, usageRecord.getOfferingId().toString());
 				usageRecResponse.setOfferingId(diskOff.getUuid());
 			}
 
 		} else if(usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO){
 			//Template/ISO ID
-			VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString());
+            VMTemplateVO tmpl = _entityMgr.findById(VMTemplateVO.class, usageRecord.getUsageId().toString());
 			usageRecResponse.setUsageId(tmpl.getUuid());
 			//Template/ISO Size
 			usageRecResponse.setSize(usageRecord.getSize());
@@ -3382,35 +3382,35 @@ public class ApiResponseHelper implements ResponseGenerator {
 
 		} else if(usageRecord.getUsageType() == UsageTypes.SNAPSHOT){
 			//Snapshot ID
-			SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString());
+            SnapshotVO snap = _entityMgr.findById(SnapshotVO.class, usageRecord.getUsageId().toString());
 			usageRecResponse.setUsageId(snap.getUuid());
 			//Snapshot Size
 			usageRecResponse.setSize(usageRecord.getSize());
 
 		} else if(usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY){
 			//Load Balancer Policy ID
-            LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class, usageRecord.getUsageId().toString());
+            LoadBalancerVO lb = _entityMgr.findById(LoadBalancerVO.class, usageRecord.getUsageId().toString());
             usageRecResponse.setUsageId(lb.getUuid());
 		} else if(usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE){
 			//Port Forwarding Rule ID
-            PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class, usageRecord.getUsageId().toString());
+            PortForwardingRuleVO pf = _entityMgr.findById(PortForwardingRuleVO.class, usageRecord.getUsageId().toString());
             usageRecResponse.setUsageId(pf.getUuid());
 
 		} else if(usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING){
 			//Network Offering Id
-			NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString());
+            NetworkOfferingVO netOff = _entityMgr.findById(NetworkOfferingVO.class, usageRecord.getOfferingId().toString());
 			usageRecResponse.setOfferingId(netOff.getUuid());
 			//is Default
 			usageRecResponse.setDefault((usageRecord.getUsageId() == 1)? true:false);
 
 		} else if(usageRecord.getUsageType() == UsageTypes.VPN_USERS){
 			//VPN User ID
-            VpnUserVO vpnUser = _entityMgr.findByIdIncludingRemoved(VpnUserVO.class, usageRecord.getUsageId().toString());
+            VpnUserVO vpnUser = _entityMgr.findById(VpnUserVO.class, usageRecord.getUsageId().toString());
             usageRecResponse.setUsageId(vpnUser.getUuid());
 
 		} else if(usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP){
 			//Security Group Id
-			SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString());
+            SecurityGroupVO sg = _entityMgr.findById(SecurityGroupVO.class, usageRecord.getUsageId().toString());
 			usageRecResponse.setUsageId(sg.getUuid());
 		}
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/server/src/com/cloud/dao/EntityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/dao/EntityManagerImpl.java b/server/src/com/cloud/dao/EntityManagerImpl.java
deleted file mode 100644
index 14ea2bf..0000000
--- a/server/src/com/cloud/dao/EntityManagerImpl.java
+++ /dev/null
@@ -1,150 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.dao;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.springframework.stereotype.Component;
-
-import net.sf.ehcache.Cache;
-
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-@Local(value=EntityManager.class)
-@SuppressWarnings("unchecked")
-public class EntityManagerImpl extends ManagerBase implements EntityManager {
-    String _name;
-    Cache _cache;
-
-    @Override
-    public <T, K extends Serializable> T findById(Class<T> entityType, K id) {
-        GenericDao<? extends T, K> dao = (GenericDao<? extends T, K>)GenericDaoBase.getDao(entityType);
-        return dao.findById(id);
-    }
-    
-    @Override
-    public <T, K extends Serializable> T findByIdIncludingRemoved(Class<T> entityType, K id) {
-        GenericDao<? extends T, K> dao = (GenericDao<? extends T, K>)GenericDaoBase.getDao(entityType);
-        return dao.findByIdIncludingRemoved(id);
-    }
-
-    @Override
-    public <T> T findByUuid(Class<T> entityType, String uuid) {
-        // Finds and returns a unique VO using uuid, null if entity not found in db
-        GenericDao<? extends T, String> dao = (GenericDao<? extends T, String>)GenericDaoBase.getDao(entityType);
-        return dao.findByUuid(uuid);
-    }
-
-    @Override
-    public <T> T findByUuidIncludingRemoved(Class<T> entityType, String uuid) {
-        // Finds and returns a unique VO using uuid, null if entity not found in db
-        GenericDao<? extends T, String> dao = (GenericDao<? extends T, String>)GenericDaoBase.getDao(entityType);
-        return dao.findByUuidIncludingRemoved(uuid);
-    }
-
-    @Override
-    public <T> T findByXId(Class<T> entityType, String xid) {
-        return null;
-    }
-
-    @Override
-    public <T> List<? extends T> list(Class<T> entityType) {
-        GenericDao<? extends T, ? extends Serializable> dao = GenericDaoBase.getDao(entityType);
-        return dao.listAll();
-    }
-
-    @Override
-    public <T> T persist(T t) {
-        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao((Class<T>)t.getClass());
-        return dao.persist(t);
-    }
-
-    @Override
-    public <T> SearchBuilder<T> createSearchBuilder(Class<T> entityType) {
-        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
-        return dao.createSearchBuilder();
-    }
-
-    @Override
-    public <T, K> GenericSearchBuilder<T, K> createGenericSearchBuilder(Class<T> entityType, Class<K> resultType) {
-        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
-        return dao.createSearchBuilder((Class<K>)resultType.getClass());
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-        /*
-        String threadId = Long.toString(Thread.currentThread().getId());
-
-        CacheManager cm = CacheManager.create();
-
-        _cache = cm.getCache(threadId);
-
-        if (_cache == null) {
-            int maxElements = NumbersUtil.parseInt((String)params.get("cache.size"), 100);
-            int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300);
-            int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300);
-
-            _cache = new Cache(threadId, maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle);
-            cm.addCache(_cache);
-
-        }*/
-        
-        return true;
-    } 
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public <T, K> List<K> search(Class<T> entityType, SearchCriteria<K> sc) {
-        GenericDao<T, ? extends Serializable> dao = (GenericDao<T, ? extends Serializable>)GenericDaoBase.getDao(entityType);
-        return dao.customSearch(sc, null);
-    }
-
-    @Override
-    public <T, K extends Serializable> void remove(Class<T> entityType, K id) {
-        GenericDao<T, K> dao = (GenericDao<T, K>)GenericDaoBase.getDao(entityType);
-        dao.remove(id);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/usage/pom.xml
----------------------------------------------------------------------
diff --git a/usage/pom.xml b/usage/pom.xml
index af08f53..2051d5e 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -28,7 +28,7 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
+      <artifactId>cloud-api</artifactId>
       <version>${project.version}</version>
       <type>test-jar</type>
       <scope>test</scope>      

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/pom.xml
----------------------------------------------------------------------
diff --git a/utils/pom.xml b/utils/pom.xml
index e8aa805..686afdd 100644
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -83,11 +83,6 @@
       <version>${cs.jsch.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.eclipse.persistence</groupId>
-      <artifactId>javax.persistence</artifactId>
-      <version>${cs.jpa.version}</version>
-    </dependency>
-    <dependency>
       <groupId>org.jasypt</groupId>
       <artifactId>jasypt</artifactId>
       <version>${cs.jasypt.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/AnnotationHelper.java b/utils/src/com/cloud/utils/AnnotationHelper.java
deleted file mode 100755
index e7a6166..0000000
--- a/utils/src/com/cloud/utils/AnnotationHelper.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils;
-
-import javax.persistence.Table;
-
-import org.apache.log4j.Logger;
-
-
-public class AnnotationHelper extends Object {
-	// This class contains routines to help query annotation elements of objects.
-
-	public static final Logger s_logger = Logger.getLogger(AnnotationHelper.class.getName());
-
-	public static String getTableName(Object proxyObj) {
-		// The cglib class is generated by cglib during runtime.
-
-		Class<?> curClass = proxyObj.getClass();
-		if (curClass == null) {
-            s_logger.trace("Could not retrieve class information for proxy object");
-			return null;
-		}
-
-		while (curClass.getSuperclass() != null && curClass.getSuperclass().getName() != "java.lang.Object") {
-			curClass = curClass.getSuperclass();
-		}
-		// At this point, curClass is the root base class of proxyObj's class, and curClass is not java.lang.Object.
-
-		Table tabObj = curClass.getAnnotation(Table.class);
-
-		if (tabObj == null) {
-            s_logger.trace(curClass + "does not have a Table annotation");
-			return null;
-		}
-
-		return tabObj.name();
-	}
-
-}
-
-
-
-


[03/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/GenericSearchBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GenericSearchBuilder.java b/utils/src/com/cloud/utils/db/GenericSearchBuilder.java
deleted file mode 100755
index bf28144..0000000
--- a/utils/src/com/cloud/utils/db/GenericSearchBuilder.java
+++ /dev/null
@@ -1,548 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Transient;
-
-import net.sf.cglib.proxy.Factory;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.SearchCriteria.SelectType;
-
-/**
- * GenericSearchBuilder is used to build a search based on a VO object
- * a convenience class provided called SearchBuilder that provides
- * exactly that functionality.
- *
- * @param <T> VO object this Search is build for.
- * @param <K> Result object that should contain the results.
- */
-public class GenericSearchBuilder<T, K> implements MethodInterceptor {
-    final protected Map<String, Attribute> _attrs;
-    
-    protected ArrayList<Condition> _conditions;
-    protected HashMap<String, JoinBuilder<GenericSearchBuilder<?, ?>>> _joins;
-    protected ArrayList<Select> _selects;
-    protected GroupBy<T, K> _groupBy = null;
-    protected Class<T> _entityBeanType;
-    protected Class<K> _resultType;
-    protected SelectType _selectType;
-    
-    protected T _entity;
-    protected ArrayList<Attribute> _specifiedAttrs;
-    
-    @SuppressWarnings("unchecked")
-    protected GenericSearchBuilder(T entity, Class<K> clazz, Map<String, Attribute> attrs) {
-        _entityBeanType = (Class<T>)entity.getClass();
-        _resultType = clazz;
-        
-        _attrs = attrs;
-        _entity = entity;
-        _conditions = new ArrayList<Condition>();
-        _joins = null;
-        _specifiedAttrs = new ArrayList<Attribute>();
-    }
-    
-    public T entity() {
-        return _entity;
-    }
-    
-    protected Attribute getSpecifiedAttribute() {
-        if (_entity == null || _specifiedAttrs == null || _specifiedAttrs.size() != 1) {
-            throw new RuntimeException("Now now, better specify an attribute or else we can't help you");
-        }
-        return _specifiedAttrs.get(0);
-    }
-
-    public GenericSearchBuilder<T, K> selectField(Object... useless) {
-        if (_entity == null) {
-            throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
-        }
-        if (_specifiedAttrs.size() <= 0) {
-            throw new RuntimeException("You didn't specify any attributes");
-        }
-   
-        if (_selects == null) {
-            _selects = new ArrayList<Select>();
-        }
-        
-        for (Attribute attr : _specifiedAttrs) {
-            Field field = null;
-            try {
-                field = _resultType.getDeclaredField(attr.field.getName());
-                field.setAccessible(true);
-            } catch (SecurityException e) {
-            } catch (NoSuchFieldException e) {
-            }
-            _selects.add(new Select(Func.NATIVE, attr, field, null));
-        }
-        
-        _specifiedAttrs.clear();
-        
-        return this;
-    }
-    
-//    public GenericSearchBuilder<T, K> selectField(String joinName, Object... entityFields) {
-//        JoinBuilder<GenericSearchBuilder<?, ?>> jb = _joins.get(joinName);
-//
-//    }
-    
-    /**
-     * Specifies the field to select.
-     * 
-     * @param fieldName The field name of the result object to put the value of the field selected.  This can be null if you're selecting only one field and the result is not a complex object.
-     * @param func function to place.
-     * @param useless column to select.  Call this with this.entity() method.
-     * @param params parameters to the function.
-     * @return a SearchBuilder to build more search parts.
-     */
-    public GenericSearchBuilder<T, K> select(String fieldName, Func func, Object useless, Object... params) {
-        if (_entity == null) {
-            throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
-        }
-        if (_specifiedAttrs.size() > 1) {
-            throw new RuntimeException("You can't specify more than one field to search on");
-        }
-        if (func.getCount() != -1 && (func.getCount() != (params.length + 1))) {
-            throw new RuntimeException("The number of parameters does not match the function param count for " + func);
-        }
-        
-        if (_selects == null) {
-            _selects = new ArrayList<Select>();
-        }
-        
-        Field field = null;
-        if (fieldName != null) {
-            try {
-                field = _resultType.getDeclaredField(fieldName);
-                field.setAccessible(true);
-            } catch (SecurityException e) {
-                throw new RuntimeException("Unable to find " + fieldName, e);
-            } catch (NoSuchFieldException e) {
-                throw new RuntimeException("Unable to find " + fieldName, e);
-            }
-        } else {
-            if (_selects.size() != 0) {
-                throw new RuntimeException(
-                        "You're selecting more than one item and yet is not providing a container class to put these items in.  So what do you expect me to do.  Spin magic?");
-            }
-        }
-        
-        Select select = new Select(func, _specifiedAttrs.size() == 0 ? null : _specifiedAttrs.get(0), field, params);
-        _selects.add(select);
-        
-        _specifiedAttrs.clear();
-        
-        return this;
-    }
-    
-    @Override
-    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
-        String name = method.getName();
-		if (method.getAnnotation(Transient.class) == null) {
-			if (name.startsWith("get")) {
-				String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
-				set(fieldName);
-				return null;
-			} else if (name.startsWith("is")) {
-				String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
-				set(fieldName);
-				return null;
-			} else {
-			    Column ann = method.getAnnotation(Column.class);
-			    if (ann != null) {
-			        String colName = ann.name();
-			        for (Map.Entry<String, Attribute> attr : _attrs.entrySet()) {
-			            if (colName.equals(attr.getValue().columnName)) {
-			                set(attr.getKey());
-			                return null;
-			            }
-			        }
-			    }
-                throw new RuntimeException("Perhaps you need to make the method start with get or is: " + method);
-			}
-		}
-        return methodProxy.invokeSuper(object, args);
-    }
-    
-    protected void set(String name) {
-        Attribute attr = _attrs.get(name);
-        assert (attr != null) : "Searching for a field that's not there: " + name;
-        _specifiedAttrs.add(attr);
-    }
-   
-    /**
-     * Adds an AND condition to the SearchBuilder.
-     * 
-     * @param name param name you will use later to set the values in this search condition.
-     * @param useless SearchBuilder.entity().get*() which refers to the field that you're searching on.
-     * @param op operation to apply to the field.
-     * @return this
-     */
-    public GenericSearchBuilder<T, K> and(String name, Object useless, Op op) {
-        constructCondition(name, " AND ", _specifiedAttrs.get(0), op);
-        return this;
-    }
-    
-    public GenericSearchBuilder<T, K> and(Object useless, Op op, String name) {
-        constructCondition(name, " AND ", _specifiedAttrs.get(0), op);
-        return this;
-    }
-
-    public Preset and(Object useless, Op op) {
-        Condition condition = constructCondition(UUID.randomUUID().toString(), " AND ", _specifiedAttrs.get(0), op);
-        return new Preset(this, condition);
-    }
-
-    public GenericSearchBuilder<T, K> and() {
-        constructCondition(null, " AND ", null, null);
-        return this;
-    }
-    
-    public GenericSearchBuilder<T, K> where() {
-        return and();
-    }
-    
-    public GenericSearchBuilder<T, K> or() {
-        constructCondition(null, " OR ", null, null);
-        return this;
-    }
-    
-    public GenericSearchBuilder<T, K> where(String name, Object useless, Op op) {
-        return and(name, useless, op);
-    }
-    
-    public GenericSearchBuilder<T, K> where(Object useless, Op op, String name) {
-        return and(name, useless, op);
-    }
-
-    public Preset where(Object useless, Op op) {
-        return and(useless, op);
-    }
-
-    public GenericSearchBuilder<T, K> left(String name, Object useless, Op op) {
-        constructCondition(name, " ( ", _specifiedAttrs.get(0), op);
-        return this;
-    }
-    
-    public GenericSearchBuilder<T, K> left(Object useless, Op op, String name) {
-        constructCondition(name, " ( ", _specifiedAttrs.get(0), op);
-        return this;
-    }
-
-    public Preset left(Object useless, Op op) {
-        Condition condition = constructCondition(UUID.randomUUID().toString(), " ( ", _specifiedAttrs.get(0), op);
-        return new Preset(this, condition);
-    }
-
-    public GenericSearchBuilder<T, K> op(Object useless, Op op, String name) {
-        return left(useless, op, name);
-    }
-
-    public Preset op(Object useless, Op op) {
-        return left(useless, op);
-    }
-
-    public GenericSearchBuilder<T, K> op(String name, Object useless, Op op) {
-        return left(name, useless, op);
-    }
-    
-    public GenericSearchBuilder<T, K> openParen(Object useless, Op op, String name) {
-        return left(name, useless, op);
-    }
-
-    public GenericSearchBuilder<T, K> openParen(String name, Object useless, Op op) {
-        return left(name, useless, op);
-    }
-    
-    public Preset openParen(Object useless, Op op) {
-        return left(useless, op);
-    }
-
-    public GroupBy<T, K> groupBy(Object... useless) {
-        assert _groupBy == null : "Can't do more than one group bys";
-        _groupBy = new GroupBy<T, K>(this);
-        
-        return _groupBy;
-    }
-    
-    protected List<Attribute> getSpecifiedAttributes() {
-        return _specifiedAttrs;
-    }
-    
-    /**
-     * Adds an OR condition to the SearchBuilder.
-     * 
-     * @param name param name you will use later to set the values in this search condition.
-     * @param useless SearchBuilder.entity().get*() which refers to the field that you're searching on.
-     * @param op operation to apply to the field.
-     * @return this
-     */
-    public GenericSearchBuilder<T, K> or(String name, Object useless, Op op) {
-        constructCondition(name, " OR ", _specifiedAttrs.get(0), op);
-        return this;
-    }
-    
-    public GenericSearchBuilder<T, K> or(Object useless, Op op, String name) {
-        constructCondition(name, " OR ", _specifiedAttrs.get(0), op);
-        return this;
-    }
-
-    public Preset or(Object useless, Op op) {
-        Condition condition = constructCondition(UUID.randomUUID().toString(), " OR ", _specifiedAttrs.get(0), op);
-        return new Preset(this, condition);
-    }
-
-    public GenericSearchBuilder<T, K> join(String name, GenericSearchBuilder<?, ?> builder, Object useless, Object useless2, JoinBuilder.JoinType joinType) {
-        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
-        assert _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
-        assert builder._entity != null : "SearchBuilder cannot be modified once it has been setup";
-        assert builder._specifiedAttrs.size() == 1 : "You didn't select the attribute.";
-        assert builder != this : "You can't add yourself, can you?  Really think about it!";
-        
-        JoinBuilder<GenericSearchBuilder<?, ?>> t = new JoinBuilder<GenericSearchBuilder<?, ?>>(builder, _specifiedAttrs.get(0), builder._specifiedAttrs.get(0), joinType);
-        if (_joins == null) {
-        	_joins = new HashMap<String, JoinBuilder<GenericSearchBuilder<?, ?>>>();
-        }
-        _joins.put(name, t);
-        
-        builder._specifiedAttrs.clear();
-        _specifiedAttrs.clear();
-        return this;
-    }
-    
-    protected Condition constructCondition(String conditionName, String cond, Attribute attr, Op op) {
-        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
-        assert op == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
-        assert op != Op.SC : "Call join";
-        
-        Condition condition = new Condition(conditionName, cond, attr, op);
-        _conditions.add(condition);
-        _specifiedAttrs.clear();
-        return condition;
-    }
-
-    /**
-     * creates the SearchCriteria so the actual values can be filled in.
-     * 
-     * @return SearchCriteria
-     */
-    public SearchCriteria<K> create() {
-        if (_entity != null) {
-            done();
-        }
-        return new SearchCriteria<K>(this);
-    }
-    
-    public SearchCriteria<K> create(String name, Object... values) {
-        SearchCriteria<K> sc = create();
-        sc.setParameters(name, values);
-        return sc;
-    }
-    
-    public GenericSearchBuilder<T, K> right() {
-        Condition condition = new Condition("rp", " ) ", null, Op.RP);
-        _conditions.add(condition);
-        return this;
-    }
-    
-    public GenericSearchBuilder<T, K> cp() {
-        return right();
-    }
-    
-    public GenericSearchBuilder<T, K> closeParen() {
-        return right();
-    }
-    
-    public SelectType getSelectType() {
-        return _selectType;
-    }
-    
-    /**
-     * Marks the SearchBuilder as completed in building the search conditions.
-     */
-    public synchronized void done() {
-        if (_entity != null) {
-            Factory factory = (Factory)_entity;
-            factory.setCallback(0, null);
-            _entity = null;
-        }
-        
-        if (_joins != null) {
-        	for (JoinBuilder<GenericSearchBuilder<?, ?>> join : _joins.values()) {
-        		join.getT().done();
-            }
-        }
-        
-        if (_selects == null || _selects.size() == 0) {
-            _selectType = SelectType.Entity;
-            assert _entityBeanType.equals(_resultType) : "Expecting " + _entityBeanType + " because you didn't specify any selects but instead got " + _resultType;
-            return;
-        }
-        
-        for (Select select : _selects) {
-            if (select.field == null) {
-                assert (_selects.size() == 1) : "You didn't specify any fields to put the result in but you're specifying more than one select so where should I put the selects?";
-                _selectType = SelectType.Single;
-                return;
-            }
-            if (select.func != null) {
-                _selectType = SelectType.Result;
-                return;
-            }
-        }
-        
-        _selectType = SelectType.Fields;
-    }
-    
-    protected static class Condition {
-        protected final String name;
-        protected final String cond;
-        protected final Op op;
-        protected final Attribute attr;
-        protected Object[] presets;
-        
-        protected Condition(String name) {
-            this(name, null, null, null);
-        }
-        
-        public Condition(String name, String cond, Attribute attr, Op op) {
-            this.name = name;
-            this.attr = attr;
-            this.cond = cond;
-            this.op = op;
-            this.presets = null;
-        }
-        
-        public boolean isPreset() {
-            return presets != null;
-        }
-
-        public void setPresets(Object... presets) {
-            this.presets = presets;
-        }
-
-        public Object[] getPresets() {
-            return presets;
-        }
-
-        public void toSql(StringBuilder sql, Object[] params, int count) {
-            if (count > 0) {
-                sql.append(cond);
-            }
-            
-            if (op == null) {
-                return;
-            }
-            
-            if (op == Op.SC) {
-                sql.append(" (").append(((SearchCriteria<?>)params[0]).getWhereClause()).append(") ");
-                return;
-            }
-            
-            if (attr == null) {
-                return;
-            }
-            
-            sql.append(attr.table).append(".").append(attr.columnName).append(op.toString());
-            if (op == Op.IN && params.length == 1) {
-                sql.delete(sql.length() - op.toString().length(), sql.length());
-                sql.append("=?");
-            } else if (op == Op.NIN && params.length == 1) {
-                sql.delete(sql.length() - op.toString().length(), sql.length());
-                sql.append("!=?");
-            } else if (op.getParams() == -1) {
-                for (int i = 0; i < params.length; i++) {
-                    sql.insert(sql.length() - 2, "?,");
-                }
-                sql.delete(sql.length() - 3, sql.length() - 2); // remove the last ,
-            } else if (op  == Op.EQ && (params == null || params.length == 0 || params[0] == null)) {
-                sql.delete(sql.length() - 4, sql.length());
-                sql.append(" IS NULL ");
-            } else if (op == Op.NEQ && (params == null || params.length == 0 || params[0] == null)) {
-                sql.delete(sql.length() - 5, sql.length());
-                sql.append(" IS NOT NULL ");
-            } else {
-                if ((op.getParams() != 0 || params != null) && (params.length != op.getParams())) {
-                    throw new RuntimeException("Problem with condition: " + name);
-                }
-            }
-        }
-        
-        @Override
-        public int hashCode() {
-            return name.hashCode();
-        }
-        
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof Condition)) {
-                return false;
-            }
-            
-            Condition condition = (Condition)obj;
-            return name.equals(condition.name);
-        }
-    }
-    
-    protected static class Select {
-        public Func func;
-        public Attribute attr;
-        public Object[] params;
-        public Field field;
-        
-        protected Select() {
-        }
-        
-        public Select(Func func, Attribute attr, Field field, Object[] params) {
-            this.func = func;
-            this.attr = attr;
-            this.params = params;
-            this.field = field;
-        }
-    }
-    
-    public class Preset {
-        GenericSearchBuilder<T, K> builder;
-        Condition condition;
-
-        protected Preset(GenericSearchBuilder<T, K> builder, Condition condition) {
-            this.builder = builder;
-            this.condition = condition;
-        }
-
-        public GenericSearchBuilder<T, K> values(Object... params) {
-            if (condition.op.getParams() > 0 && condition.op.params != params.length) {
-                throw new RuntimeException("The # of parameters set " + params.length + " does not match # of parameters required by " + condition.op);
-            }
-            condition.setPresets(params);
-            return builder;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/GlobalLock.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GlobalLock.java b/utils/src/com/cloud/utils/db/GlobalLock.java
deleted file mode 100644
index c956bbf..0000000
--- a/utils/src/com/cloud/utils/db/GlobalLock.java
+++ /dev/null
@@ -1,244 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import static java.lang.String.format;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.Profiler;
-
-//
-// Wrapper class for global database lock to reduce contention for database connections from within process
-//
-// Example of using dynamic named locks
-//
-//		GlobalLock lock = GlobalLock.getInternLock("some table name" + rowId);
-//		
-//		if(lock.lock()) {
-//			try {
-//				do something
-//			} finally {
-//				lock.unlock();
-//			}
-//		}
-//		lock.releaseRef();
-//
-public class GlobalLock {
-    protected final static Logger s_logger = Logger.getLogger(GlobalLock.class);
-
-	private String name;
-	private int lockCount = 0;
-	private Thread ownerThread = null;
-	
-	private int referenceCount = 0;
-	private long holdingStartTick = 0;
-	
-	private static Map<String, GlobalLock> s_lockMap = new HashMap<String, GlobalLock>();
-	
-	private GlobalLock(String name) {
-		this.name = name;
-	}
-	
-	public int addRef() {
-		synchronized(this) {
-			referenceCount++;
-			return referenceCount;
-		}
-	}
-	
-	public int releaseRef() {
-		int refCount;
-		
-		boolean needToRemove = false;
-		synchronized(this) {
-			referenceCount--;
-			refCount = referenceCount;
-			
-			if(referenceCount < 0)
-				s_logger.warn("Unmatched Global lock " + name + " reference usage detected, check your code!");
-			
-			if(referenceCount == 0)
-				needToRemove = true;
-		}
-		
-		if(needToRemove)
-			releaseInternLock(name);
-		
-		return refCount;
-	}
-
-	public static GlobalLock getInternLock(String name) {
-		synchronized(s_lockMap) {
-			if(s_lockMap.containsKey(name)) {
-				GlobalLock lock = s_lockMap.get(name);
-				lock.addRef();
-				return lock;
-			} else {
-				GlobalLock lock = new GlobalLock(name);
-				lock.addRef();
-				s_lockMap.put(name, lock);
-				return lock;
-			}
-		}
-	}
-	
-	private static void releaseInternLock(String name) {
-		synchronized(s_lockMap) {
-			GlobalLock lock = s_lockMap.get(name);
-			if(lock != null) {
-				if(lock.referenceCount == 0)
-					s_lockMap.remove(name);
-			} else {
-				s_logger.warn("Releasing " + name + ", but it is already released.");
-			}
-		}
-	}
-	
-	public boolean lock(int timeoutSeconds) {
-		int remainingMilliSeconds = timeoutSeconds*1000;
-		Profiler profiler = new Profiler();
-		boolean interrupted = false;
-		try {
-			while(true) {
-				synchronized(this) {
-					if(ownerThread != null && ownerThread == Thread.currentThread()) {
-						s_logger.warn("Global lock re-entrance detected");
-						
-						lockCount++;
-	
-						if(s_logger.isTraceEnabled())
-							s_logger.trace("lock " + name + " is acquired, lock count :" + lockCount);
-						return true;
-					}
-					
-					if(ownerThread != null) {
-						profiler.start();
-						try {
-							wait(((long)timeoutSeconds)*1000L);
-						} catch (InterruptedException e) {
-							interrupted = true;
-						}
-						profiler.stop();
-						
-						remainingMilliSeconds -= profiler.getDuration();
-						if(remainingMilliSeconds < 0)
-							return false;
-						
-						continue;
-					} else {
-						// take ownership temporarily to prevent others enter into stage of acquiring DB lock
-						ownerThread = Thread.currentThread();
-						addRef();
-					}
-				}
-
-				if(DbUtil.getGlobalLock(name, remainingMilliSeconds / 1000)) {
-					synchronized(this) {
-						lockCount++;
-						holdingStartTick = System.currentTimeMillis();
-						
-						if(s_logger.isTraceEnabled())
-							s_logger.trace("lock " + name + " is acquired, lock count :" + lockCount);
-						return true;
-					}
-				} else {
-					synchronized(this) {
-						ownerThread = null;
-						releaseRef();
-						return false;
-					}
-				}
-			}
-		} finally {
-			if(interrupted) {
-				Thread.currentThread().interrupt();
-			}
-		}
-	}
-	
-	public boolean unlock() {
-		synchronized(this) {
-			if(ownerThread != null && ownerThread == Thread.currentThread()) {
-				lockCount--;
-				if(lockCount == 0) {
-					ownerThread = null;
-					DbUtil.releaseGlobalLock(name);
-					
-					if(s_logger.isTraceEnabled())
-						s_logger.trace("lock " + name + " is returned to free state, total holding time :" + 
-							(System.currentTimeMillis() - holdingStartTick));
-					holdingStartTick = 0;
-					
-					// release holding position in intern map when we released the DB connection
-					releaseRef();
-					notifyAll();
-				}
-				
-				if(s_logger.isTraceEnabled())
-					s_logger.trace("lock " + name + " is released, lock count :" + lockCount);
-				return true;
-			}
-			return false;
-		}
-	}
-	
-	public String getName() {
-		return name;
-	}
-
-    public static <T> T executeWithLock(final String operationId,
-            final int lockAcquisitionTimeout, final Callable<T> operation)
-            throws Exception {
-
-        final GlobalLock lock = GlobalLock.getInternLock(operationId);
-
-        try {
-
-            if (!lock.lock(lockAcquisitionTimeout)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(format(
-                            "Failed to acquire lock for operation id %1$s",
-                            operationId));
-                }
-                return null;
-            }
-
-            return operation.call();
-
-        } finally {
-
-            if (lock != null) {
-                lock.unlock();
-            }
-
-        }
-
-    }
-
-    public static <T> T executeWithNoWaitLock(final String operationId,
-            final Callable<T> operation) throws Exception {
-
-        return executeWithLock(operationId, 0, operation);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/GroupBy.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GroupBy.java b/utils/src/com/cloud/utils/db/GroupBy.java
deleted file mode 100644
index 3b9cd19..0000000
--- a/utils/src/com/cloud/utils/db/GroupBy.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-
-public class GroupBy<T, R> {
-    GenericSearchBuilder<T, R> _builder;
-    List<Pair<Func, Attribute>> _groupBys;
-    Having _having;
-    
-    public GroupBy(GenericSearchBuilder<T, R> builder) {
-        _builder = builder;
-        _groupBys = new ArrayList<Pair<Func, Attribute>>();
-        _having = null;
-        for (Attribute attr : _builder.getSpecifiedAttributes()) {
-            _groupBys.add(new Pair<Func, Attribute>(null, attr));
-        }
-        _builder.getSpecifiedAttributes().clear();
-    }
-    
-    public GroupBy<T, R> group(Object useless) {
-        _groupBys.add(new Pair<Func, Attribute>(null, _builder.getSpecifiedAttributes().get(0)));
-        _builder.getSpecifiedAttributes().clear();
-        return this; 
-    }
-    
-    public GroupBy<T, R> group(Func func, Object useless) {
-        _groupBys.add(new Pair<Func, Attribute>(func, _builder.getSpecifiedAttributes().get(0)));
-        _builder.getSpecifiedAttributes().clear();
-        return this;
-    }
-    
-    public GenericSearchBuilder<T, R> having(Func func, Object obj, Op op, Object value) {
-        assert(_having == null) : "You can only specify one having in a group by";
-        List<Attribute> attrs = _builder.getSpecifiedAttributes();
-        assert attrs.size() == 1 : "You didn't specified an attribute";
-        
-        _having = new Having(func, attrs.get(0), op, value);
-        _builder.getSpecifiedAttributes().clear();
-        return _builder;
-    }
-    
-    public void toSql(StringBuilder builder) {
-        builder.append(" GROUP BY ");
-        for (Pair<Func, Attribute> groupBy : _groupBys) {
-            if (groupBy.first() != null) {
-                String func = groupBy.first().toString();
-                func.replaceFirst("@", groupBy.second().table + "." + groupBy.second().columnName);
-                builder.append(func);
-            } else {
-                builder.append(groupBy.second().table + "." + groupBy.second().columnName);
-            }
-            
-            builder.append(", ");
-        }
-        
-        builder.delete(builder.length() - 2, builder.length());
-        if (_having != null) {
-            _having.toSql(builder);
-        }
-    }
-    
-    protected class Having {
-        public Func func;
-        public Attribute attr;
-        public Op op;
-        public Object value;
-        
-        public Having(Func func, Attribute attr, Op op, Object value) {
-            this.func = func;
-            this.attr = attr;
-            this.op = op;
-            this.value = value;
-        }
-        
-        public void toSql(StringBuilder builder) {
-            if (func != null) {
-                String f = func.toString();
-                f.replaceFirst("@", attr.toString());
-                builder.append(func);
-            } else {
-                builder.append(attr.toString());
-            }
-            
-            builder.append(op.toString());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/JoinBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/JoinBuilder.java b/utils/src/com/cloud/utils/db/JoinBuilder.java
deleted file mode 100644
index c4920c4..0000000
--- a/utils/src/com/cloud/utils/db/JoinBuilder.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-
-public class JoinBuilder<T> {
-	
-	public enum JoinType {
-	     INNER ("INNER JOIN"),
-	     LEFT ("LEFT JOIN"),
-	     RIGHT ("RIGHT JOIN"),
-	     RIGHTOUTER ("RIGHT OUTER JOIN"),
-	     LEFTOUTER ("LEFT OUTER JOIN");
-	     
-	     private final String _name;
-	     
-	     JoinType(String name) {
-	            _name = name;
-	     }
-	     
-	     public String getName() { return _name; }
-	}
-
-	
-	private T t;
-	private JoinType type;
-	private Attribute firstAttribute;
-	private Attribute secondAttribute;
-	
-	public JoinBuilder(T t, Attribute firstAttribute,
-			Attribute secondAttribute, JoinType type) {
-		this.t = t;
-		this.firstAttribute = firstAttribute;
-		this.secondAttribute = secondAttribute;
-		this.type = type;
-	}
-	
-	public T getT() {
-		return t;
-	}
-	public void setT(T t) {
-		this.t = t;
-	}
-	public JoinType getType() {
-		return type;
-	}
-	public void setType(JoinType type) {
-		this.type = type;
-	}
-	public Attribute getFirstAttribute() {
-		return firstAttribute;
-	}
-	public void setFirstAttribute(Attribute firstAttribute) {
-		this.firstAttribute = firstAttribute;
-	}
-	public Attribute getSecondAttribute() {
-		return secondAttribute;
-	}
-	public void setSecondAttribute(Attribute secondAttribute) {
-		this.secondAttribute = secondAttribute;
-	}
-
-}
-
-

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/JoinType.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/JoinType.java b/utils/src/com/cloud/utils/db/JoinType.java
deleted file mode 100755
index 6861925..0000000
--- a/utils/src/com/cloud/utils/db/JoinType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * JoinType is only used with SecondaryTable.  Temporary solution.   
- */
-@Target(TYPE)
-@Retention(RUNTIME)
-public @interface JoinType {
-    String type() default "inner";
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/Merovingian2.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Merovingian2.java b/utils/src/com/cloud/utils/db/Merovingian2.java
deleted file mode 100644
index 0e0e8f2..0000000
--- a/utils/src/com/cloud/utils/db/Merovingian2.java
+++ /dev/null
@@ -1,461 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-
-import javax.management.StandardMBean;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.mgmt.JmxUtil;
-import com.cloud.utils.time.InaccurateClock;
-
-
-public class Merovingian2 extends StandardMBean implements MerovingianMBean {
-    private static final Logger s_logger = Logger.getLogger(Merovingian2.class);
-
-    private static final String ACQUIRE_SQL = "INSERT INTO op_lock (op_lock.key, op_lock.mac, op_lock.ip, op_lock.thread, op_lock.acquired_on, waiters) VALUES (?, ?, ?, ?, ?, 1)";
-    private static final String INCREMENT_SQL = "UPDATE op_lock SET waiters=waiters+1 where op_lock.key=? AND op_lock.mac=? AND op_lock.ip=? AND op_lock.thread=?";
-    private static final String SELECT_SQL = "SELECT op_lock.key, mac, ip, thread, acquired_on, waiters FROM op_lock";
-    private static final String INQUIRE_SQL = SELECT_SQL + " WHERE op_lock.key=?";
-    private static final String DECREMENT_SQL = "UPDATE op_lock SET waiters=waiters-1 where op_lock.key=? AND op_lock.mac=? AND op_lock.ip=? AND op_lock.thread=?";
-    private static final String RELEASE_LOCK_SQL = "DELETE FROM op_lock WHERE op_lock.key = ?";
-    private static final String RELEASE_SQL = RELEASE_LOCK_SQL + " AND op_lock.mac=? AND waiters=0";
-    private static final String CLEANUP_MGMT_LOCKS_SQL = "DELETE FROM op_lock WHERE op_lock.mac = ?";
-    private static final String SELECT_MGMT_LOCKS_SQL = SELECT_SQL + " WHERE mac=?";
-    private static final String SELECT_THREAD_LOCKS_SQL = SELECT_SQL + " WHERE mac=? AND ip=?";
-    private static final String CLEANUP_THREAD_LOCKS_SQL = "DELETE FROM op_lock WHERE mac=? AND ip=? AND thread=?";
-
-    TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
-
-    private final long _msId;
-
-    private static Merovingian2 s_instance = null;
-    private ConnectionConcierge _concierge = null;
-    private static ThreadLocal<Count> s_tls = new ThreadLocal<Count>();
-
-    private Merovingian2(long msId) {
-        super(MerovingianMBean.class, false);
-        _msId = msId;
-        Connection conn = null;
-        try {
-            conn = Transaction.getStandaloneConnectionWithException();
-            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
-            conn.setAutoCommit(true);
-            _concierge = new ConnectionConcierge("LockMaster", conn, true);
-        } catch (SQLException e) {
-            s_logger.error("Unable to get a new db connection", e);
-            throw new CloudRuntimeException("Unable to initialize a connection to the database for locking purposes: ", e);
-        }
-    }
-
-    public static synchronized Merovingian2 createLockMaster(long msId) {
-        assert s_instance == null : "No lock can serve two masters.  Either he will hate the one and love the other, or he will be devoted to the one and despise the other.";
-        s_instance = new Merovingian2(msId);
-        s_instance.cleanupThisServer();
-        try {
-            JmxUtil.registerMBean("Locks", "Locks", s_instance);
-        } catch (Exception e) {
-            s_logger.error("Unable to register for JMX", e);
-        }
-        return s_instance;
-    }
-
-    public static Merovingian2 getLockMaster() {
-        return s_instance;
-    }
-
-
-    protected void incrCount() {
-        Count count = s_tls.get();
-        if (count == null) {
-            count = new Count();
-            s_tls.set(count);
-        }
-
-        count.count++;
-    }
-
-    protected void decrCount() {
-        Count count = s_tls.get();
-        if (count == null) {
-            return;
-        }
-
-        count.count--;
-    }
-
-
-    public boolean acquire(String key, int timeInSeconds) {
-        Thread th = Thread.currentThread();
-        String threadName = th.getName();
-        int threadId = System.identityHashCode(th);
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Acquiring lck-" + key + " with wait time of " + timeInSeconds);
-        }
-        long startTime = InaccurateClock.getTime();
-
-        while ((InaccurateClock.getTime() - startTime) < (timeInSeconds * 1000)) {
-            int count = owns(key);
-
-            if (count >= 1) {
-                return increment(key, threadName, threadId);
-            } else if (count == 0) {
-                if (doAcquire(key, threadName, threadId)) {
-                    return true;
-                }
-            }
-            try {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Sleeping more time while waiting for lck-" + key);
-                }
-                Thread.sleep(5000);
-            } catch (InterruptedException e) {
-            }
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Timed out on acquiring lock " + key + ".  Waited for " + (InaccurateClock.getTime() - startTime));
-        }
-        return false;
-    }
-
-    protected boolean increment(String key, String threadName, int threadId) {
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = _concierge.conn().prepareStatement(INCREMENT_SQL);
-            pstmt.setString(1, key);
-            pstmt.setLong(2, _msId);
-            pstmt.setString(3, threadName);
-            pstmt.setInt(4, threadId);
-            int rows = pstmt.executeUpdate();
-            assert (rows <= 1) : "hmm...non unique key? " + pstmt;
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("lck-" + key + (rows == 1 ? " acquired again" : " failed to acquire again"));
-            }
-            if (rows == 1) {
-                incrCount();
-                return true;
-            }
-            return false;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to increment " + key, e);
-        } finally {
-            try {
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-            }
-        }
-    }
-
-    protected boolean doAcquire(String key, String threadName, int threadId) {
-        PreparedStatement pstmt = null;
-
-        long startTime = InaccurateClock.getTime();
-        try {
-            pstmt = _concierge.conn().prepareStatement(ACQUIRE_SQL);
-            pstmt.setString(1, key);
-            pstmt.setLong(2, _msId);
-            pstmt.setString(3, threadName);
-            pstmt.setInt(4, threadId);
-            pstmt.setString(5, DateUtil.getDateDisplayString(s_gmtTimeZone, new Date()));
-            try {
-                int rows = pstmt.executeUpdate();
-                if (rows == 1) {
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Acquired for lck-" + key);
-                    }
-                    incrCount();
-                    return true;
-                }
-            } catch(SQLException e) {
-                if (!(e.getSQLState().equals("23000") && e.getErrorCode() == 1062)) {
-                    throw new CloudRuntimeException("Unable to lock " + key + ".  Waited " + (InaccurateClock.getTime() - startTime), e);
-                }
-            }
-        } catch(SQLException e) {
-            throw new CloudRuntimeException("Unable to lock " + key + ".  Waited " + (InaccurateClock.getTime() - startTime), e);
-        } finally {
-            try {
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-            }
-        }
-
-        s_logger.trace("Unable to acquire lck-" + key);
-        return false;
-    }
-
-    protected Map<String, String> isLocked(String key) {
-        PreparedStatement pstmt = null;
-        ResultSet rs = null;
-        try {
-            pstmt = _concierge.conn().prepareStatement(INQUIRE_SQL);
-            pstmt.setString(1, key);
-            rs = pstmt.executeQuery();
-            if (!rs.next()) {
-                return null;
-            }
-
-            return toLock(rs);
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("SQL Exception on inquiry", e);
-        } finally {
-            try {
-                if (rs != null) {
-                    rs.close();
-                }
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-                s_logger.warn("Unexpected SQL exception " + e.getMessage(), e);
-            }
-        }
-    }
-
-    public void cleanupThisServer() {
-        cleanupForServer(_msId);
-    }
-
-    @Override
-    public void cleanupForServer(long msId) {
-        s_logger.info("Cleaning up locks for " + msId);
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = _concierge.conn().prepareStatement(CLEANUP_MGMT_LOCKS_SQL);
-            pstmt.setLong(1, msId);
-            int rows = pstmt.executeUpdate();
-            s_logger.info("Released " + rows + " locks for " + msId);
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to clear the locks", e);
-        } finally {
-            try {
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-            }
-        }
-    }
-
-    public boolean release(String key) {
-        PreparedStatement pstmt = null;
-        Thread th = Thread.currentThread();
-        String threadName = th.getName();
-        int threadId = System.identityHashCode(th);
-        try {
-            pstmt = _concierge.conn().prepareStatement(DECREMENT_SQL);
-            pstmt.setString(1, key);
-            pstmt.setLong(2, _msId);
-            pstmt.setString(3, threadName);
-            pstmt.setLong(4, threadId);
-            int rows = pstmt.executeUpdate();
-            assert (rows <= 1) : "hmmm....keys not unique? " + pstmt;
-           
-            
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("lck-" + key + " released");
-            }
-            if (rows == 1) {
-                pstmt.close();
-                pstmt = _concierge.conn().prepareStatement(RELEASE_SQL);
-                pstmt.setString(1, key);
-                pstmt.setLong(2, _msId);
-                int result = pstmt.executeUpdate();
-                if (result == 1 && s_logger.isTraceEnabled()) {
-                    s_logger.trace("lck-" + key + " removed");
-                }
-                decrCount();
-            } else  if (rows < 1) {
-                s_logger.warn("Was unable to find lock for the key " + key + " and thread id " + threadId);
-            }
-            
-            return rows == 1;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to release " + key, e);
-        } finally {
-            try {
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-            }
-        }
-    }
-
-    protected Map<String, String> toLock(ResultSet rs) throws SQLException {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put("key", rs.getString(1));
-        map.put("mgmt", rs.getString(2));
-        map.put("name", rs.getString(3));
-        map.put("tid", Integer.toString(rs.getInt(4)));
-        map.put("date", rs.getString(5));
-        map.put("count", Integer.toString(rs.getInt(6)));
-        return map;
-
-    }
-
-    protected List<Map<String, String>> toLocks(ResultSet rs) throws SQLException {
-        LinkedList<Map<String, String>> results = new LinkedList<Map<String, String>>();
-        while (rs.next()) {
-            results.add(toLock(rs));
-        }
-        return results;
-    }
-
-    protected List<Map<String, String>> getLocks(String sql, Long msId) {
-        PreparedStatement pstmt = null;
-        ResultSet rs = null;
-        try {
-            pstmt = _concierge.conn().prepareStatement(sql);
-            if (msId != null) {
-                pstmt.setLong(1, msId);
-            }
-            rs = pstmt.executeQuery();
-            return toLocks(rs);
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to retrieve locks ", e);
-        } finally {
-            try {
-                if (rs != null) {
-                    rs.close();
-                }
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch(SQLException e) {
-            }
-        }
-    }
-
-    @Override
-    public List<Map<String, String>> getAllLocks() {
-        return getLocks(SELECT_SQL, null);
-    }
-
-    @Override
-    public List<Map<String, String>> getLocksAcquiredByThisServer() {
-        return getLocks(SELECT_MGMT_LOCKS_SQL, _msId);
-    }
-
-    public int owns(String key) {
-        Thread th = Thread.currentThread();
-        int threadId = System.identityHashCode(th);
-        Map<String, String> owner = isLocked(key);
-        if (owner == null) {
-            return 0;
-        }
-        if (owner.get("mgmt").equals(Long.toString(_msId)) && owner.get("tid").equals(Integer.toString(threadId))) {
-            return Integer.parseInt(owner.get("count"));
-        }
-        return -1;
-    }
-
-    public List<Map<String, String>> getLocksAcquiredBy(long msId, String threadName) {
-        PreparedStatement pstmt = null;
-        ResultSet rs = null;
-        try {
-            pstmt = _concierge.conn().prepareStatement(SELECT_THREAD_LOCKS_SQL);
-            pstmt.setLong(1, msId);
-            pstmt.setString(2, threadName);
-            rs = pstmt.executeQuery();
-            return toLocks(rs);
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Can't get locks " + pstmt, e);
-        } finally {
-            try {
-                if (rs != null) {
-                    rs.close();
-                }
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-            }
-        }
-    }
-
-    public void cleanupThread() {
-
-        Count count = s_tls.get();
-        if (count == null || count.count == 0) {
-            return;
-        }
-
-        int c = count.count;
-
-        count.count = 0;
-
-        Thread th = Thread.currentThread();
-        String threadName = th.getName();
-        int threadId = System.identityHashCode(th);
-
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = _concierge.conn().prepareStatement(CLEANUP_THREAD_LOCKS_SQL);
-            pstmt.setLong(1, _msId);
-            pstmt.setString(2, threadName);
-            pstmt.setInt(3, threadId);
-            int rows = pstmt.executeUpdate();
-            assert (false) : "Abandon hope, all ye who enter here....There were still " + rows + ":" + c + " locks not released when the transaction ended, check for lock not released or @DB is not added to the code that using the locks!";
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Can't clear locks " + pstmt, e);
-        } finally {
-            try {
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-            }
-        }
-    }
-
-    @Override
-    public boolean releaseLockAsLastResortAndIReallyKnowWhatIAmDoing(String key) {
-        s_logger.info("Releasing a lock from JMX lck-" + key);
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = _concierge.conn().prepareStatement(RELEASE_LOCK_SQL);
-            pstmt.setString(1, key);
-            int rows = pstmt.executeUpdate();
-            return rows > 0;
-        } catch (SQLException e) {
-            s_logger.error("Unable to release lock " + key, e);
-            return false;
-        }
-    }
-    protected static class Count {
-        public int count = 0;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/MerovingianMBean.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/MerovingianMBean.java b/utils/src/com/cloud/utils/db/MerovingianMBean.java
deleted file mode 100644
index e9ee955..0000000
--- a/utils/src/com/cloud/utils/db/MerovingianMBean.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.List;
-import java.util.Map;
-
-
-public interface MerovingianMBean {
-    
-    List<Map<String, String>> getAllLocks();
-    
-    List<Map<String, String>> getLocksAcquiredByThisServer();
-    
-    boolean releaseLockAsLastResortAndIReallyKnowWhatIAmDoing(String key);
-    
-    void cleanupForServer(long msId);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/ScriptRunner.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/ScriptRunner.java b/utils/src/com/cloud/utils/db/ScriptRunner.java
deleted file mode 100644
index d579de7..0000000
--- a/utils/src/com/cloud/utils/db/ScriptRunner.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class
- * from the iBATIS Apache project. Only removed dependency on Resource class
- * and a constructor 
- */
-/*
- *  Copyright 2004 Clinton Begin
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package com.cloud.utils.db;
-
-import java.io.IOException;
-import java.io.LineNumberReader;
-import java.io.Reader;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import org.apache.log4j.Logger;
-
-/**
- * Tool to run database scripts
- */
-public class ScriptRunner {
-    private static Logger s_logger = Logger.getLogger(ScriptRunner.class); 
-
-    private static final String DEFAULT_DELIMITER = ";";
-
-    private Connection connection;
-
-    private boolean stopOnError;
-    private boolean autoCommit;
-    private boolean verbosity = true;
-
-    private String delimiter = DEFAULT_DELIMITER;
-    private boolean fullLineDelimiter = false;
-
-    private StringBuffer _logBuffer = new StringBuffer();
-
-    /**
-     * Default constructor
-     */
-    public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) {
-        this.connection = connection;
-        this.autoCommit = autoCommit;
-        this.stopOnError = stopOnError;
-    }
-
-    public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError, boolean verbosity) {
-        this.connection = connection;
-        this.autoCommit = autoCommit;
-        this.stopOnError = stopOnError;
-        this.verbosity = verbosity;
-    }
-
-    public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
-        this.delimiter = delimiter;
-        this.fullLineDelimiter = fullLineDelimiter;
-    }
-
-    /**
-     * Runs an SQL script (read in using the Reader parameter)
-     * 
-     * @param reader
-     *            - the source of the script
-     */
-    public void runScript(Reader reader) throws IOException, SQLException {
-        try {
-            boolean originalAutoCommit = connection.getAutoCommit();
-            try {
-                if (originalAutoCommit != this.autoCommit) {
-                    connection.setAutoCommit(this.autoCommit);
-                }
-                runScript(connection, reader);
-            } finally {
-                connection.setAutoCommit(originalAutoCommit);
-            }
-        } catch (IOException e) {
-            throw e;
-        } catch (SQLException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new RuntimeException("Error running script.  Cause: " + e, e);
-        }
-    }
-
-    /**
-     * Runs an SQL script (read in using the Reader parameter) using the
-     * connection passed in
-     * 
-     * @param conn
-     *            - the connection to use for the script
-     * @param reader
-     *            - the source of the script
-     * @throws SQLException
-     *             if any SQL errors occur
-     * @throws IOException
-     *             if there is an error reading from the Reader
-     */
-    private void runScript(Connection conn, Reader reader) throws IOException, SQLException {
-        StringBuffer command = null;
-        try {
-            LineNumberReader lineReader = new LineNumberReader(reader);
-            String line = null;
-            while ((line = lineReader.readLine()) != null) {
-                if (command == null) {
-                    command = new StringBuffer();
-                }
-                String trimmedLine = line.trim();
-                if (trimmedLine.startsWith("--")) {
-                    println(trimmedLine);
-                } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("//")) {
-                    // Do nothing
-                } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("--")) {
-                    // Do nothing
-                } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("#")) { 
-                    // Do nothing  
-                } else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter()) || fullLineDelimiter && trimmedLine.equals(getDelimiter())) {
-                    command.append(line.substring(0, line.lastIndexOf(getDelimiter())));
-                    command.append(" ");
-                    Statement statement = conn.createStatement();
-
-                    println(command);
-
-                    boolean hasResults = false;
-                    if (stopOnError) {
-                        hasResults = statement.execute(command.toString());
-                    } else {
-                        try {
-                            statement.execute(command.toString());
-                        } catch (SQLException e) {
-                            e.fillInStackTrace();
-                            printlnError("Error executing: " + command);
-                            printlnError(e);
-                        }
-                    }
-
-                    if (autoCommit && !conn.getAutoCommit()) {
-                        conn.commit();
-                    }
-
-                    ResultSet rs = statement.getResultSet();
-                    if (hasResults && rs != null) {
-                        ResultSetMetaData md = rs.getMetaData();
-                        int cols = md.getColumnCount();
-                        for (int i = 0; i < cols; i++) {
-                            String name = md.getColumnLabel(i);
-                            print(name + "\t");
-                        }
-                        println("");
-                        while (rs.next()) {
-                            for (int i = 0; i < cols; i++) {
-                                String value = rs.getString(i);
-                                print(value + "\t");
-                            }
-                            println("");
-                        }
-                    }
-
-                    command = null;
-                    try {
-                        statement.close();
-                    } catch (Exception e) {
-                        // Ignore to workaround a bug in Jakarta DBCP
-                    }
-                    Thread.yield();
-                } else {
-                    int idx = line.indexOf("--");
-                    if (idx != -1)
-                        command.append(line.substring(0, idx));
-                    else
-                        command.append(line);
-                    command.append(" ");
-                }
-            }
-            if (!autoCommit) {
-                conn.commit();
-            }
-        } catch (SQLException e) {
-            e.fillInStackTrace();
-            printlnError("Error executing: " + command);
-            printlnError(e);
-            throw e;
-        } catch (IOException e) {
-            e.fillInStackTrace();
-            printlnError("Error executing: " + command);
-            printlnError(e);
-            throw e;
-        } finally {
-            conn.rollback();
-            flush();
-        }
-    }
-
-    private String getDelimiter() {
-        return delimiter;
-    }
-
-    private void print(Object o) {
-        _logBuffer.append(o);
-    }
-
-    private void println(Object o) {
-        _logBuffer.append(o);
-        if (verbosity)
-            s_logger.debug(_logBuffer.toString());
-        _logBuffer = new StringBuffer();
-    }
-
-    private void printlnError(Object o) {
-        s_logger.error("" + o);
-    }
-
-    private void flush() {
-        if (_logBuffer.length() > 0) {
-            s_logger.debug(_logBuffer.toString());
-            _logBuffer = new StringBuffer();
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/SearchBuilder.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SearchBuilder.java b/utils/src/com/cloud/utils/db/SearchBuilder.java
deleted file mode 100755
index c177e20..0000000
--- a/utils/src/com/cloud/utils/db/SearchBuilder.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.Map;
-
-/**
- * SearchBuilder is meant as a static query construct.  Often times in DAO code,
- * we write static sql that just assumes the database table does not change.
- * change by hand.  SearchBuilder is meant to replace that.  It provides load-time
- * 
- *   1. SearchBuilder is declared as final because it should not change after load time.
- *   2. search.entity().getHostId() allows you to declare which field you are searching
- *      on.  By doing this, we take advantage of the compiler to check that we
- *      are not searching on obsolete fields.  You should try to use this
- *      as much as possible as oppose to the addAndByField() and addOrByField() methods.
- *   3. Note that the same SearchBuilder is used to create multiple SearchCriteria.
- *      This is equivalent to clearing the parameters on PreparedStatement.  The
- *      multiple SearchCriteria does not interfere with each other.
- *   4. Note that the same field (getHostId()) was specified with two param
- *      names.  This is basically allowing you to reuse the same field in two
- *      parts of the search.
- * 
- * {@code
- * final SearchBuilder<UserVmVO> search = _userVmDao.createSearchBuilder();
- * final String param1 = "param1";
- * final String param2 = "param2";
- * search.addAnd(param1, search.entity().getHostId(), SearchCriteria.Op.NEQ);
- * search.addAnd(param2, search.entity().getHostId(), SearchCriteria.op.GT);
- * ...
- * SearchCriteria sc = search.create();
- * sc.setParameters(param1, 3);
- * sc.setParameters(param2, 1);
- * 
- * ...
- * 
- * SearchCriteria sc2 = search.create();
- * sc2.setParameters(param1, 4);
- * sc2.setParameters(param2, 1);
- * }
- * 
- * @param <T> VO object.
- */
-public class SearchBuilder<T> extends GenericSearchBuilder<T, T> {
-    
-    @SuppressWarnings("unchecked")
-    public SearchBuilder(T entity, Map<String, Attribute> attrs) {
-        super(entity, (Class<T>)entity.getClass(), attrs);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/SearchCriteria.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SearchCriteria.java b/utils/src/com/cloud/utils/db/SearchCriteria.java
deleted file mode 100755
index 22bccd3..0000000
--- a/utils/src/com/cloud/utils/db/SearchCriteria.java
+++ /dev/null
@@ -1,364 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.GenericSearchBuilder.Condition;
-import com.cloud.utils.db.GenericSearchBuilder.Select;
-
-/**
- * big joins or high performance searches, it is much better to
- */
-public class SearchCriteria<K> {
-    public enum Op {
-        GT(" > ? ", 1),
-        GTEQ(" >= ? ", 1),
-        LT(" < ? ", 1),
-        LTEQ(" <= ? ", 1),
-        EQ(" = ? ", 1),
-        NEQ(" != ? ", 1),
-        BETWEEN(" BETWEEN ? AND ? ", 2),
-        NBETWEEN(" NOT BETWEEN ? AND ? ", 2),
-        IN(" IN () ", -1),
-        NOTIN(" NOT IN () ", -1),
-        LIKE(" LIKE ? ", 1),
-        NLIKE(" NOT LIKE ? ", 1),
-        NIN(" NOT IN () ", -1),
-        NULL(" IS NULL ", 0),
-        NNULL(" IS NOT NULL ", 0),
-        SC(" () ", 1),
-        TEXT("  () ", 1),
-        RP("", 0),
-        AND(" AND ", 0),
-        OR(" OR ", 0),
-        NOT(" NOT ", 0);
-
-        private final String op;
-        int params;
-        Op(String op, int params) {
-            this.op = op;
-            this.params = params;
-        }
-
-        @Override
-        public String toString() {
-            return op;
-        }
-
-        public int getParams() {
-            return params;
-        }
-    }
-
-    public enum Func {
-        NATIVE("@", 1),
-        MAX("MAX(@)", 1),
-        MIN("MIN(@)", 1),
-        FIRST("FIRST(@)", 1),
-        LAST("LAST(@)", 1),
-        SUM("SUM(@)", 1),
-        COUNT("COUNT(@)", 1),
-        DISTINCT("DISTINCT(@)", 1);
-
-        private String func;
-        private int count;
-
-        Func(String func, int params) {
-            this.func = func;
-            this.count = params;
-        }
-
-        @Override
-        public String toString() {
-            return func;
-        }
-
-        public int getCount() {
-            return count;
-        }
-    }
-
-    public enum SelectType {
-        Fields,
-        Entity,
-        Single,
-        Result
-    }
-
-    private final Map<String, Attribute> _attrs;
-    private final ArrayList<Condition> _conditions;
-    private ArrayList<Condition> _additionals = null;
-    private HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
-    private int _counter;
-    private HashMap<String, JoinBuilder<SearchCriteria<?>>> _joins;
-    private final ArrayList<Select> _selects;
-    private final GroupBy<?, K> _groupBy;
-    private final List<Object> _groupByValues;
-    private final Class<K> _resultType;
-    private final SelectType _selectType;
-
-    protected SearchCriteria(final Map<String, Attribute> attrs, ArrayList<GenericSearchBuilder.Condition> conditions, ArrayList<Select> selects, SelectType selectType, Class<K> resultType, HashMap<String, Object[]> params) {
-        this._attrs = attrs;
-        this._conditions = conditions;
-        this._selects = selects;
-        this._selectType = selectType;
-        this._resultType = resultType;
-        this._params = params;
-        this._additionals = new ArrayList<Condition>();
-        this._counter = 0;
-        this._joins = null;
-        this._groupBy = null;
-        this._groupByValues = null;
-    }
-
-    protected SearchCriteria(GenericSearchBuilder<?, K> sb) {
-        this._attrs = sb._attrs;
-        this._conditions = sb._conditions;
-        this._additionals = new ArrayList<Condition>();
-        this._counter = 0;
-        this._joins = null;
-        if (sb._joins != null) {
-            _joins = new HashMap<String, JoinBuilder<SearchCriteria<?>>>(sb._joins.size());
-            for (Map.Entry<String, JoinBuilder<GenericSearchBuilder<?, ?>>> entry : sb._joins.entrySet()) {
-                JoinBuilder<GenericSearchBuilder<?, ?>> value =  entry.getValue();
-                _joins.put(entry.getKey(), new JoinBuilder<SearchCriteria<?>>(value.getT().create(),value.getFirstAttribute(), value.getSecondAttribute(), value.getType()));
-            }
-        }
-        _selects = sb._selects;
-        _groupBy = sb._groupBy;
-        if (_groupBy != null) {
-            _groupByValues = new ArrayList<Object>();
-        } else {
-            _groupByValues = null;
-        }
-        _resultType = sb._resultType;
-        _selectType = sb._selectType;
-    }
-
-    public SelectType getSelectType() {
-        return _selectType;
-    }
-
-    public void getSelect(StringBuilder str, int insertAt) {
-        if (_selects == null || _selects.size() == 0) {
-            return;
-        }
-
-        for (Select select : _selects) {
-            String func = select.func.toString() + ",";
-            if (select.attr == null) {
-                func = func.replace("@", "*");
-            } else {
-                func = func.replace("@", select.attr.table + "." + select.attr.columnName);
-            }
-            str.insert(insertAt, func);
-            insertAt += func.length();
-            if (select.field == null) {
-                break;
-            }
-        }
-
-        str.delete(insertAt - 1, insertAt);
-    }
-
-    public List<Field> getSelectFields() {
-        List<Field> fields = new ArrayList<Field>(_selects.size());
-        for (Select select : _selects) {
-            fields.add(select.field);
-        }
-
-        return fields;
-    }
-
-    public void setParameters(String conditionName, Object... params) {
-        assert _conditions.contains(new Condition(conditionName)) || _additionals.contains(new Condition(conditionName)) : "Couldn't find " + conditionName;
-        _params.put(conditionName, params);
-    }
-
-    public boolean isSelectAll() {
-        return _selects == null || _selects.size() == 0;
-    }
-
-    protected JoinBuilder<SearchCriteria<?>> findJoin(Map<String, JoinBuilder<SearchCriteria<?>>> jbmap, String joinName) {
-    	JoinBuilder<SearchCriteria<?>> jb = jbmap.get(joinName);
-    	if (jb != null) {
-    		return jb;
-    	}
-    	
-    	for (JoinBuilder<SearchCriteria<?>> j2 : jbmap.values()) {
-    		SearchCriteria<?> sc = j2.getT();
-    		if(sc._joins != null)
-    		    jb = findJoin(sc._joins, joinName);
-    		if (jb != null) {
-    			return jb;
-    		}
-    	}
-    	
-    	assert (false) : "Unable to find a join by the name " + joinName;
-    	return null;
-    }
-
-    public void setJoinParameters(String joinName, String conditionName, Object... params) {
-        JoinBuilder<SearchCriteria<?>> join = findJoin(_joins, joinName);
-        assert (join != null) : "Incorrect join name specified: " + joinName;
-        join.getT().setParameters(conditionName, params);
-
-    }
-
-    public void addJoinAnd(String joinName, String field, Op op, Object... values) {
-        JoinBuilder<SearchCriteria<?>> join = _joins.get(joinName);
-        assert (join != null) : "Incorrect join name specified: " + joinName;
-        join.getT().addAnd(field, op, values);
-    }
-
-    public void addJoinOr(String joinName, String field, Op op, Object... values) {
-        JoinBuilder<SearchCriteria<?>> join = _joins.get(joinName);
-        assert (join != null) : "Incorrect join name specified: " + joinName;
-        join.getT().addOr(field, op, values);
-    }
-
-    public SearchCriteria<?> getJoin(String joinName) {
-        return _joins.get(joinName).getT();
-    }
-
-    public Pair<GroupBy<?, ?>, List<Object>> getGroupBy() {
-        return _groupBy == null ? null : new Pair<GroupBy<?, ?>, List<Object>>(_groupBy, _groupByValues);
-    }
-
-    public void setGroupByValues(Object... values) {
-        for (Object value : values) {
-            _groupByValues.add(value);
-        }
-    }
-
-    public Class<K> getResultType() {
-        return _resultType;
-    }
-
-    public void addAnd(String field, Op op, Object... values) {
-        String name = Integer.toString(_counter++);
-        addCondition(name, " AND ", field, op);
-        setParameters(name, values);
-    }
-
-    public void addAnd(Attribute attr, Op op, Object... values) {
-        String name = Integer.toString(_counter++);
-        addCondition(name, " AND ", attr, op);
-        setParameters(name, values);
-    }
-
-    public void addOr(String field, Op op, Object... values) {
-        String name = Integer.toString(_counter++);
-        addCondition(name, " OR ", field, op);
-        setParameters(name, values);
-    }
-
-    public void addOr(Attribute attr, Op op, Object... values) {
-        String name = Integer.toString(_counter++);
-        addCondition(name, " OR ", attr, op);
-        setParameters(name, values);
-    }
-
-    protected void addCondition(String conditionName, String cond, String fieldName, Op op) {
-        Attribute attr = _attrs.get(fieldName);
-        assert attr != null : "Unable to find field: " + fieldName;
-        addCondition(conditionName, cond, attr, op);
-    }
-
-    protected void addCondition(String conditionName, String cond, Attribute attr, Op op) {
-        Condition condition = new Condition(conditionName, /*(_conditions.size() + _additionals.size()) == 0 ? "" : */cond, attr, op);
-        _additionals.add(condition);
-    }
-
-    public String getWhereClause() {
-        StringBuilder sql = new StringBuilder();
-        int i = 0;
-        for (Condition condition : _conditions) {
-            if (condition.isPreset()) {
-                _params.put(condition.name, condition.presets);
-            }
-            Object[] params = _params.get(condition.name);
-            if ((condition.op == null || condition.op.params == 0) || (params != null)) {
-                condition.toSql(sql, params, i++);
-            }
-        }
-
-        for (Condition condition : _additionals) {
-            if (condition.isPreset()) {
-                _params.put(condition.name, condition.presets);
-            }
-            Object[] params = _params.get(condition.name);
-            if ((condition.op.params == 0) || (params != null)) {
-                condition.toSql(sql, params, i++);
-            }
-        }
-
-        return sql.toString();
-    }
-
-    public List<Pair<Attribute, Object>> getValues() {
-        ArrayList<Pair<Attribute, Object>> params = new ArrayList<Pair<Attribute, Object>>(_params.size());
-        for (Condition condition : _conditions) {
-            Object[] objs = _params.get(condition.name);
-            if (condition.op != null && condition.op.params != 0 && objs != null) {
-                getParams(params, condition, objs);
-            }
-        }
-
-        for (Condition condition : _additionals) {
-            Object[] objs = _params.get(condition.name);
-            if ((condition.op.params == 0) || (objs != null)) {
-                getParams(params, condition, objs);
-            }
-        }
-
-        return params;
-    }
-
-    public Collection<JoinBuilder<SearchCriteria<?>>> getJoins() {
-        return _joins != null ? _joins.values() : null;
-    }
-
-    private void getParams(ArrayList<Pair<Attribute, Object>> params, Condition condition, Object[] objs) {
-        if (condition.op == Op.SC) {
-            assert (objs != null && objs.length > 0) : " Where's your search criteria object? " + condition.name;
-            params.addAll(((SearchCriteria<?>)objs[0]).getValues());
-            return;
-        }
-
-        if (objs != null && objs.length > 0) {
-            for (Object obj : objs) {
-                if ((condition.op != Op.EQ && condition.op != Op.NEQ) || (obj != null)) {
-                    params.add(new Pair<Attribute, Object>(condition.attr, obj));
-                }
-            }
-        }
-    }
-
-    public Pair<String, ArrayList<Object>> toSql() {
-        StringBuilder sql = new StringBuilder();
-
-        return new Pair<String, ArrayList<Object>>(sql.toString(), null);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/SearchCriteria2.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SearchCriteria2.java b/utils/src/com/cloud/utils/db/SearchCriteria2.java
deleted file mode 100755
index 5875106..0000000
--- a/utils/src/com/cloud/utils/db/SearchCriteria2.java
+++ /dev/null
@@ -1,213 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.persistence.Transient;
-
-import net.sf.cglib.proxy.Factory;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-
-import com.cloud.utils.db.GenericSearchBuilder.Condition;
-import com.cloud.utils.db.GenericSearchBuilder.Select;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.SearchCriteria.SelectType;
-
-public class SearchCriteria2<T, K> implements SearchCriteriaService<T, K>, MethodInterceptor{
-	GenericDao<? extends Serializable, ? extends Serializable> _dao;
-	final protected Map<String, Attribute> _attrs;
-	protected ArrayList<Attribute> _specifiedAttrs;
-	protected T _entity;
-	protected ArrayList<GenericSearchBuilder.Condition> _conditions;
-	protected ArrayList<Select> _selects;
-	private final HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
-	protected Class<K> _resultType;
-    protected SelectType _selectType;
-    protected Class<T> _entityBeanType;
-	
-	protected SearchCriteria2(T entity, Class<K> resultType, final Map<String, Attribute> attrs, GenericDao<? extends Serializable, ? extends Serializable> dao) {
-		_entityBeanType = (Class<T>)entity.getClass();
-		_dao = dao;
-		_resultType = resultType;
-		_attrs = attrs;
-		_entity = entity;
-		_conditions = new ArrayList<Condition>();
-		_specifiedAttrs = new ArrayList<Attribute>();
-    }
-	
-	static public <T, K> SearchCriteria2<T, K> create(Class<T> entityType, Class<K> resultType) {
-		GenericDao<? extends Serializable, ? extends Serializable> dao = (GenericDao<? extends Serializable, ? extends Serializable>)GenericDaoBase.getDao(entityType);
-		assert dao != null : "Can not find DAO for " + entityType.getName();
-		SearchCriteria2<T, K> sc = dao.createSearchCriteria2(resultType);
-		return sc;
-	}
-	
-	static public <T, K> SearchCriteria2<T, K> create(Class<T> entityType) {
-		GenericDao<? extends Serializable, ? extends Serializable> dao = (GenericDao<? extends Serializable, ? extends Serializable>)GenericDaoBase.getDao(entityType);
-		assert dao != null : "Can not find DAO for " + entityType.getName();
-		SearchCriteria2<T, K> sc = dao.createSearchCriteria2();
-		return sc;
-	}
-	
-	@Override
-	public void selectField(Object... useless) {
-        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
-        assert _specifiedAttrs.size() > 0 : "You didn't specify any attributes";
-   
-        if (_selects == null) {
-            _selects = new ArrayList<Select>();
-        }
-        
-        for (Attribute attr : _specifiedAttrs) {
-            Field field = null;
-            try {
-                field = _resultType.getDeclaredField(attr.field.getName());
-                field.setAccessible(true);
-            } catch (SecurityException e) {
-            } catch (NoSuchFieldException e) {
-            }
-            _selects.add(new Select(Func.NATIVE, attr, field, null));
-        }
-        
-        _specifiedAttrs.clear();
-    }
-	
-    private void constructCondition(String conditionName, String cond, Attribute attr, Op op) {
-        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
-        assert op == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
-        assert op != Op.SC : "Call join";
-        
-        GenericSearchBuilder.Condition condition = new GenericSearchBuilder.Condition(conditionName, cond, attr, op);
-        _conditions.add(condition);
-        _specifiedAttrs.clear();
-    }
-    
-    private void setParameters(String conditionName, Object... params) {
-        assert _conditions.contains(new Condition(conditionName)) : "Couldn't find " + conditionName;
-        _params.put(conditionName, params);
-    }
-    
-	@Override
-	public void addAnd(Object useless, Op op, Object...values) {
-		String uuid = UUID.randomUUID().toString();
-		constructCondition(uuid, " AND ", _specifiedAttrs.get(0), op);
-		setParameters(uuid, values);
-	}
-	
-	@Override
-	public List<K> list() {
-		done();
-		SearchCriteria sc1 = createSearchCriteria();
-		if (isSelectAll()) {
-			return (List<K>)_dao.search(sc1, null);
-		} else {
-			return (List<K>)_dao.customSearch(sc1, null);
-		}
-	}
-	
-	private boolean isSelectAll() {
-        return _selects == null || _selects.size() == 0;
-    }
-	
-	@Override
-	public T getEntity() {
-		return (T) _entity; 
-	}
-
-	private SearchCriteria<K> createSearchCriteria() {
-		return new SearchCriteria<K>(_attrs, _conditions, _selects, _selectType, _resultType, _params);
-	}
-	
-    private void set(String name) {
-        Attribute attr = _attrs.get(name);
-        assert (attr != null) : "Searching for a field that's not there: " + name;
-        _specifiedAttrs.add(attr);
-    }
-    
-    private void done() {
-        if (_entity != null) {
-            Factory factory = (Factory)_entity;
-            factory.setCallback(0, null);
-            _entity = null;
-        }
-                
-        if (_selects == null || _selects.size() == 0) {
-            _selectType = SelectType.Entity;
-            assert _entityBeanType.equals(_resultType) : "Expecting " + _entityBeanType + " because you didn't specify any selects but instead got " + _resultType;
-            return;
-        }
-        
-        for (Select select : _selects) {
-            if (select.field == null) {
-                assert (_selects.size() == 1) : "You didn't specify any fields to put the result in but you're specifying more than one select so where should I put the selects?";
-                _selectType = SelectType.Single;
-                return;
-            }
-            if (select.func != null) {
-                _selectType = SelectType.Result;
-                return;
-            }
-        }
-        
-        _selectType = SelectType.Fields;
-    }
-    
-	@Override
-	public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
-		String name = method.getName();
-		if (method.getAnnotation(Transient.class) == null) {
-			if (name.startsWith("get")) {
-				String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
-				set(fieldName);
-				return null;
-			} else if (name.startsWith("is")) {
-				String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
-				set(fieldName);
-				return null;
-			} else {
-				name = name.toLowerCase();
-				for (String fieldName : _attrs.keySet()) {
-					if (name.endsWith(fieldName.toLowerCase())) {
-						set(fieldName);
-						return null;
-					}
-				}
-				assert false : "Perhaps you need to make the method start with get or is?";
-			}
-		}
-        return methodProxy.invokeSuper(object, args);
-    }
-
-	@Override
-    public <K> K find() {
-		assert isSelectAll() : "find doesn't support select search";
-		done();
-		SearchCriteria sc1 = createSearchCriteria();
-		return (K)_dao.findOneBy(sc1);
-    }
-
-}


[09/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/GenericDao.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/GenericDao.java b/framework/db/src/com/cloud/utils/db/GenericDao.java
new file mode 100755
index 0000000..66d0f67
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/GenericDao.java
@@ -0,0 +1,284 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.Pair;
+
+/**
+ * a uniform method for persisting and finding db entities.
+ **/
+public interface GenericDao<T, ID extends Serializable> {
+ 
+    /**
+     */
+    static final String REMOVED_COLUMN = "cloud_removed";
+    
+    static final String REMOVED = "removed";
+    
+    /**
+     * This column can be used if the table wants to track creation time.
+     */
+    static final String CREATED_COLUMN = "created";
+    
+    /**
+     */
+    static final String XID_COLUMN = "xid";
+    
+    /**
+     * Look for an entity bean using the database id.  Does not lock the row.
+     * @param id database unique id for the entity bean.
+     * @return entity bean.
+     **/
+    T findById(ID id);
+    
+    T findByIdIncludingRemoved(ID id);
+    
+    T findById(ID id, boolean fresh);
+
+    // Finds one unique VO using uuid
+    T findByUuid(String uuid);
+
+    // Finds one unique VO using uuid including removed entities
+    T findByUuidIncludingRemoved(String uuid);
+    
+    /**
+     * @return VO object ready to be used for update.  It won't have any fields filled in.
+     */
+    T createForUpdate();
+    
+    SearchBuilder<T> createSearchBuilder();
+    <K> GenericSearchBuilder<T, K> createSearchBuilder(Class<K> clazz);
+    
+    T createForUpdate(ID id);
+    
+    /**
+     * Returns a SearchCriteria object that can be used to build search conditions.
+     * 
+     * @return SearchCriteria
+     */
+    SearchCriteria<T> createSearchCriteria();
+    
+    /**
+     * lock the rows that matched the search criteria and filter.  This method needs
+     * to be called within a transaction.
+     * 
+     * @param sc SearchCriteria containing the different search conditions
+     * @param filter Filter containing limits etc
+     * @param exclusive exclusive or share lock
+     * @return List<T> list of entity beans
+     */
+    List<T> lockRows(SearchCriteria<T> sc, Filter filter, boolean exclusive);
+    
+    /**
+     * lock 1 of the return set.  This method needs to be run within a
+     * transaction or else it's useless.
+     * @param sc
+     * @param exclusive
+     * @return T if found and locked.  null if not.
+     */
+    T lockOneRandomRow(SearchCriteria<T> sc, boolean exclusive);
+    
+    /**
+     * Find and lock the row for update.
+     * @param id id
+     * @param exclusive is this a read share lock or exclusive lock?
+     * @return T
+     */
+    T lockRow(ID id, Boolean exclusive);
+
+    /**
+     * Acquires a database wide lock on the id of the entity.  This ensures
+     * that only one is being used.  The timeout is the configured default.
+     * 
+     * @param id id of the entity to acquire an lock on.
+     * @return object if acquired; null if not.  If null, you need to call findById to see if it is actually not found.
+     */
+    T acquireInLockTable(ID id);
+    
+    /**
+     * Acquires a database wide lock on the id of the entity.  This ensures
+     * that only one is being used.  The timeout is the configured default.
+     * 
+     * @param id id of the entity to acquire an lock on.
+     * @param seconds time to wait for the lock.
+     * @return entity if the lock is acquired; null if not.
+     */
+    T acquireInLockTable(ID id, int seconds);
+    
+    /**
+     * releases the lock acquired in the acquire method call.
+     * @param id id of the entity to release the lock on.
+     * @return true if it is released.  false if not or not found.
+     */
+    boolean releaseFromLockTable(final ID id);
+    
+    boolean update(ID id, T entity);
+    
+    int update(T entity, SearchCriteria<T> sc);
+    
+    /**
+     * Look for all active rows.
+     * @return list of entity beans.
+     */
+    List<T> listAll();
+
+    /**
+     * Look for all active rows.
+     * @param filter filter to limit the results
+     * @return list of entity beans.
+     */
+    List<T> listAll(Filter filter);
+    
+    
+    /**
+     * Search for the entity beans
+     * @param sc
+     * @param filter
+     * @return list of entity beans.
+     */
+    List<T> search(SearchCriteria<T> sc, Filter filter);
+    
+
+    /**
+     * Search for the entity beans using the sql SQL_CACHE option
+     * @param sc
+     * @param filter
+     * @param enable_query_cache
+     * @return list of entity beans.
+     */
+    List<T> search(SearchCriteria<T> sc, Filter filter, final boolean enable_query_cache);
+    
+    
+    List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache);
+    
+
+    List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enable_query_cache);
+    
+    
+    /**
+     * Customized search with SearchCritiria
+     * @param sc
+     * @param filter
+     * @return list of entity beans.
+     */
+    public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, Filter filter);
+    
+    /**
+     * Retrieves the entire table.
+     * @return collection of entity beans.
+     **/
+    List<T> listAllIncludingRemoved();
+
+    /**
+     * Retrieves the entire table.
+     * @param filter filter to limit the returns.
+     * @return collection of entity beans.
+     **/
+    List<T> listAllIncludingRemoved(Filter filter);
+    
+    /**
+     * Persist the entity bean.  The id field of the entity is updated with
+     * the new id.
+     * @param entity the bean to persist.
+     * @return The persisted version of the object.  A null is returned if
+     * there's no primary key specified in the VO object.
+     **/
+    T persist(T entity);
+    
+    /**
+     * remove the entity bean.  This will call delete automatically if
+     * the entity bean does not have a removed field.
+     * @param id
+     * @return true if removed.
+     */
+    boolean remove(ID id);
+    
+    /**
+     * Remove based on the search criteria.  This will delete if the VO object
+     * does not have a REMOVED column.
+     * @param sc search criteria to match
+     * @return rows removed.
+     */
+    int remove(SearchCriteria<T> sc);
+    
+    /**
+     * Expunge actually delete the row even if it's REMOVED.
+     * @param id
+     * @return true if removed.
+     */
+    boolean expunge(ID id);
+    
+    /**
+     * remove the entity bean specified by the search criteria
+     * @param sc
+     * @return number of rows deleted
+     */
+    int expunge(final SearchCriteria<T> sc);
+    
+    /**
+     * expunge the removed rows.
+     */
+    void expunge();
+    
+    public <K> K getNextInSequence(Class<K> clazz, String name);
+    
+    /**
+     * Configure.
+     * @param name name of the dao.
+     * @param params params if any are specified.
+     * @return true if config is good.  false if not.
+     */
+    boolean configure(String name, Map<String, Object> params) throws ConfigurationException;
+    
+    <M> List<M> customSearch(SearchCriteria<M> sc, Filter filter);
+
+    boolean lockInLockTable(String id);
+
+    boolean lockInLockTable(String id, int seconds);
+
+    boolean unlockFromLockTable(String id);
+
+    public <K> K getRandomlyIncreasingNextInSequence(Class<K> clazz, String name);
+
+    <K> SearchCriteria2 createSearchCriteria2(Class<K> resultType);
+
+    SearchCriteria2 createSearchCriteria2();
+
+    public T findOneBy(final SearchCriteria<T> sc);
+
+    /**
+     * @return
+     */
+    Class<T> getEntityBeanType();
+    
+    public int getRegionId();
+
+    /**
+     * @param sc
+     * @param filter
+     * @return
+     */
+    Pair<List<T>, Integer> searchAndCount(SearchCriteria<T> sc, Filter filter);
+
+    Map<String, Attribute> getAllAttributes();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
new file mode 100755
index 0000000..f593c38
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
@@ -0,0 +1,1890 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.naming.ConfigurationException;
+import javax.persistence.AttributeOverride;
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.EntityExistsException;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.NoOp;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.ComponentLifecycleBase;
+import com.cloud.utils.component.ComponentMethodInterceptable;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.utils.db.SearchCriteria.SelectType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+import edu.emory.mathcs.backport.java.util.Collections;
+
+/**
+ *  GenericDaoBase is a simple way to implement DAOs.  It DOES NOT
+ *  support the full EJB3 spec.  It borrows some of the annotations from
+ *  the EJB3 spec to produce a set of SQLs so developers don't have to
+ *  copy and paste the same code over and over again.  Of course,
+ *  GenericDaoBase is completely at the mercy of the annotations you add
+ *  to your entity bean.  If GenericDaoBase does not fit your needs, then
+ *  don't extend from it.
+ * 
+ *  GenericDaoBase attempts to achieve the following:
+ *    1. If you use _allFieldsStr in your SQL statement and use to() to convert
+ *       the result to the entity bean, you don't ever have to worry about
+ *       missing fields because its automatically taken from the entity bean's
+ *       annotations.
+ *    2. You don't have to rewrite the same insert and select query strings
+ *       in all of your DAOs.
+ *    3. You don't have to match the '?' (you know what I'm talking about) to
+ *       the fields in the insert statement as that's taken care of for you.
+ * 
+ *  GenericDaoBase looks at the following annotations:
+ *    1. Table - just name
+ *    2. Column - just name
+ *    3. GeneratedValue - any field with this annotation is not inserted.
+ *    4. SequenceGenerator - sequence generator
+ *    5. Id
+ *    6. SecondaryTable
+ * 
+ *  Sometime later, I might look into injecting the SQLs as needed but right
+ *  now we have to construct them at construction time.  The good thing is that
+ *  the DAOs are suppose to be one per jvm so the time is all during the
+ *  initial load.
+ * 
+ **/
+@DB
+public abstract class GenericDaoBase<T, ID extends Serializable> extends ComponentLifecycleBase implements GenericDao<T, ID>, ComponentMethodInterceptable {
+    private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class);
+
+    protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
+
+    protected final static Map<Class<?>, GenericDao<?, ? extends Serializable>> s_daoMaps = new ConcurrentHashMap<Class<?>, GenericDao<?, ? extends Serializable>>(71);
+
+    protected Class<T> _entityBeanType;
+    protected String _table;
+
+    protected String _tables;
+
+    protected Field[] _embeddedFields;
+
+    // This is private on purpose.  Everyone should use createPartialSelectSql()
+    private final Pair<StringBuilder, Attribute[]> _partialSelectSql;
+    private final Pair<StringBuilder, Attribute[]> _partialQueryCacheSelectSql;
+    protected StringBuilder _discriminatorClause;
+    protected Map<String, Object> _discriminatorValues;
+    protected String _selectByIdSql;
+    protected String _count;
+
+    protected Field _idField;
+
+    protected List<Pair<String, Attribute[]>> _insertSqls;
+    protected Pair<String, Attribute> _removed;
+    protected Pair<String, Attribute[]> _removeSql;
+    protected List<Pair<String, Attribute[]>> _deleteSqls;
+    protected Map<String, Attribute[]> _idAttributes;
+    protected Map<String, TableGenerator> _tgs;
+    protected Map<String, Attribute> _allAttributes;
+    protected List<Attribute> _ecAttributes;
+    protected Map<Pair<String, String>, Attribute> _allColumns;
+    protected Enhancer _enhancer;
+    protected Factory _factory;
+    protected Enhancer _searchEnhancer;
+    protected int _timeoutSeconds;
+
+    protected final static CallbackFilter s_callbackFilter = new UpdateFilter();
+
+    protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE ";
+    protected static final String SHARE_MODE_CLAUSE = " LOCK IN SHARE MODE";
+    protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()";
+
+    protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance();
+
+    public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
+        @SuppressWarnings("unchecked")
+        GenericDao<? extends J, ? extends Serializable> dao = (GenericDao<? extends J, ? extends Serializable>)s_daoMaps.get(entityType);
+        assert dao != null : "Unable to find DAO for " + entityType + ".  Are you sure you waited for the DAO to be initialized before asking for it?";
+        return dao;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked") @DB(txn=false)
+    public <J> GenericSearchBuilder<T, J> createSearchBuilder(Class<J> resultType) {
+        final T entity = (T)_searchEnhancer.create();
+        final Factory factory = (Factory)entity;
+        GenericSearchBuilder<T, J> builder = new GenericSearchBuilder<T, J>(entity, resultType, _allAttributes);
+        factory.setCallback(0, builder);
+        return builder;
+    }
+
+    @Override
+    public Map<String, Attribute> getAllAttributes() {
+        return _allAttributes;
+    }
+    
+    @SuppressWarnings("unchecked")
+    protected GenericDaoBase() {
+        Type t = getClass().getGenericSuperclass();
+        if (t instanceof ParameterizedType) {
+            _entityBeanType = (Class<T>)((ParameterizedType)t).getActualTypeArguments()[0];
+        } else if (((Class<?>)t).getGenericSuperclass() instanceof ParameterizedType) {
+            _entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)t).getGenericSuperclass()).getActualTypeArguments()[0];
+        } else {
+            _entityBeanType = (Class<T>)((ParameterizedType)
+                    ( (Class<?>)((Class<?>)t).getGenericSuperclass()).getGenericSuperclass()).getActualTypeArguments()[0];
+        }
+
+        s_daoMaps.put(_entityBeanType, this);
+        Class<?>[] interphaces = _entityBeanType.getInterfaces();
+        if (interphaces != null) {
+            for (Class<?> interphace : interphaces) {
+                s_daoMaps.put(interphace, this);
+            }
+        }
+  
+        _table = DbUtil.getTableName(_entityBeanType);
+
+        final SqlGenerator generator = new SqlGenerator(_entityBeanType);
+        _partialSelectSql = generator.buildSelectSql(false);
+        _count = generator.buildCountSql();
+        _partialQueryCacheSelectSql = generator.buildSelectSql(true);
+        _embeddedFields = generator.getEmbeddedFields();
+        _insertSqls = generator.buildInsertSqls();
+        final Pair<StringBuilder, Map<String, Object>> dc = generator.buildDiscriminatorClause();
+        _discriminatorClause = dc.first().length() == 0 ? null : dc.first();
+        _discriminatorValues = dc.second();
+
+        _idAttributes = generator.getIdAttributes();
+        _idField = _idAttributes.get(_table).length > 0 ? _idAttributes.get(_table)[0].field : null;
+
+        _tables = generator.buildTableReferences();
+
+        _allAttributes = generator.getAllAttributes();
+        _allColumns = generator.getAllColumns();
+
+        _selectByIdSql = buildSelectByIdSql(createPartialSelectSql(null, true));
+        _removeSql = generator.buildRemoveSql();
+        _deleteSqls = generator.buildDeleteSqls();
+        _removed = generator.getRemovedAttribute();
+        _tgs = generator.getTableGenerators();
+        _ecAttributes = generator.getElementCollectionAttributes();
+
+        TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class);
+        if (tg != null) {
+            _tgs.put(tg.name(), tg);
+        }
+        tg = this.getClass().getSuperclass().getAnnotation(TableGenerator.class);
+        if (tg != null) {
+            _tgs.put(tg.name(), tg);
+        }
+
+        Callback[] callbacks = new Callback[] { NoOp.INSTANCE, new UpdateBuilder(this) };
+
+        _enhancer = new Enhancer();
+        _enhancer.setSuperclass(_entityBeanType);
+        _enhancer.setCallbackFilter(s_callbackFilter);
+        _enhancer.setCallbacks(callbacks);
+        _factory = (Factory)_enhancer.create();
+
+        _searchEnhancer = new Enhancer();
+        _searchEnhancer.setSuperclass(_entityBeanType);
+        _searchEnhancer.setCallback(new UpdateBuilder(this));
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Select SQL: " + _partialSelectSql.first().toString());
+            s_logger.trace("Remove SQL: " + (_removeSql != null ? _removeSql.first() : "No remove sql"));
+            s_logger.trace("Select by Id SQL: " + _selectByIdSql);
+            s_logger.trace("Table References: " + _tables);
+            s_logger.trace("Insert SQLs:");
+            for (final Pair<String, Attribute[]> insertSql : _insertSqls) {
+                s_logger.trace(insertSql.first());
+            }
+
+            s_logger.trace("Delete SQLs");
+            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
+                s_logger.trace(deletSql.first());
+            }
+
+            s_logger.trace("Collection SQLs");
+            for (Attribute attr : _ecAttributes) {
+                EcInfo info = (EcInfo)attr.attache;
+                s_logger.trace(info.insertSql);
+                s_logger.trace(info.selectSql);
+            }
+        }
+        
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_SYSTEM);
+    }
+
+    @Override @DB(txn=false)
+    @SuppressWarnings("unchecked")
+    public T createForUpdate(final ID id) {
+        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
+        if (id != null) {
+            try {
+                _idField.set(entity, id);
+            } catch (final IllegalArgumentException e) {
+            } catch (final IllegalAccessException e) {
+            }
+        }
+        return entity;
+    }
+
+    @Override @DB(txn=false)
+    public T createForUpdate() {
+        return createForUpdate(null);
+    }
+
+    @Override @DB(txn=false)
+    public <K> K getNextInSequence(final Class<K> clazz, final String name) {
+        final TableGenerator tg = _tgs.get(name);
+        assert (tg != null) : "Couldn't find Table generator using " + name;
+
+        return s_seqFetcher.getNextSequence(clazz, tg);
+    }
+
+    @Override @DB(txn=false)
+    public <K> K getRandomlyIncreasingNextInSequence(final Class<K> clazz, final String name) {
+        final TableGenerator tg = _tgs.get(name);
+        assert (tg != null) : "Couldn't find Table generator using " + name;
+
+        return s_seqFetcher.getRandomNextSequence(clazz, tg);
+    }
+
+    @Override @DB(txn=false)
+    public List<T> lockRows(final SearchCriteria<T> sc, final Filter filter, final boolean exclusive) {
+        return search(sc, filter, exclusive, false);
+    }
+
+    @Override @DB(txn=false)
+    public T lockOneRandomRow(final SearchCriteria<T> sc, final boolean exclusive) {
+        final Filter filter = new Filter(1);
+        final List<T> beans = search(sc, filter, exclusive, true);
+        return beans.isEmpty() ? null : beans.get(0);
+    }
+
+    @DB(txn=false)
+    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
+        if (_removed != null) {
+            if (sc == null) {
+                sc = createSearchCriteria();
+            }
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return searchIncludingRemoved(sc, filter, lock, cache);
+    }
+
+    @DB(txn=false)
+    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enable_query_cache) {
+        if (_removed != null) {
+            if (sc == null) {
+                sc = createSearchCriteria();
+            }
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return searchIncludingRemoved(sc, filter, lock, cache, enable_query_cache);
+    }
+
+    @Override
+    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
+        return searchIncludingRemoved(sc, filter, lock, cache, false) ;
+    }
+
+    @Override
+    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock,
+            final boolean cache, final boolean enable_query_cache) {
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createPartialSelectSql(sc, clause != null, enable_query_cache);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        List<Object> groupByValues = addGroupBy(str, sc);
+        addFilter(str, filter);
+
+        final Transaction txn = Transaction.currentTxn();
+        if (lock != null) {
+            assert (txn.dbTxnStarted() == true) : "As nice as I can here now....how do you lock when there's no DB transaction?  Review your db 101 course from college.";
+            str.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
+        }
+
+        final String sql = str.toString();
+
+        PreparedStatement pstmt = null;
+        final List<T> result = new ArrayList<T>();
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(++i, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+
+            if (s_logger.isDebugEnabled() && lock != null) {
+                txn.registerLock(pstmt.toString());
+            }
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(toEntityBean(rs, cache));
+            }
+            return result;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @Override @SuppressWarnings("unchecked")
+    public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, final Filter filter) {
+        if (sc.isSelectAll()) {
+            return (List<M>)searchIncludingRemoved((SearchCriteria<T>)sc, filter, null, false);
+        }
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createPartialSelectSql(sc, clause != null);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        List<Object> groupByValues = addGroupBy(str, sc);
+        addFilter(str, filter);
+
+        final String sql = str.toString();
+
+        final Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(++i, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+
+            ResultSet rs = pstmt.executeQuery();
+            SelectType st = sc.getSelectType();
+            ArrayList<M> results = new ArrayList<M>();
+            List<Field> fields = sc.getSelectFields();
+            while (rs.next()) {
+                if (st == SelectType.Entity) {
+                    results.add((M)toEntityBean(rs, false));
+                } else if (st == SelectType.Fields || st == SelectType.Result) {
+                    M m = sc.getResultType().newInstance();
+                    for (int j = 1; j <= fields.size(); j++) {
+                        setField(m, fields.get(j - 1), rs, j);
+                    }
+                    results.add(m);
+                } else if (st == SelectType.Single) {
+                    results.add(getObject(sc.getResultType(), rs, 1));
+                }
+            }
+
+            return results;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @Override @DB(txn=false)
+    public <M> List<M> customSearch(SearchCriteria<M> sc, final Filter filter) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+
+        return customSearchIncludingRemoved(sc, filter);
+    }
+
+    @DB(txn=false)
+    protected void setField(Object entity, Field field, ResultSet rs, int index) throws SQLException {
+        try {
+            final Class<?> type = field.getType();
+            if (type == String.class) {
+                byte[] bytes = rs.getBytes(index);
+                if(bytes != null) {
+                    try {
+                        Encrypt encrypt = field.getAnnotation(Encrypt.class);
+                        if (encrypt != null && encrypt.encrypt()){
+                            field.set(entity, DBEncryptionUtil.decrypt(new String(bytes, "UTF-8")));
+                        } else {
+                            field.set(entity, new String(bytes, "UTF-8"));
+                        }
+                    } catch (IllegalArgumentException e) {
+                        assert(false);
+                        throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data");
+                    } catch (UnsupportedEncodingException e) {
+                        assert(false);
+                        throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data");
+                    }
+                } else {
+                    field.set(entity, null);
+                }
+            } else if (type == long.class) {
+                field.setLong(entity, rs.getLong(index));
+            } else if (type == Long.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getLong(index));
+                }
+            } else if (type.isEnum()) {
+                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
+                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
+
+                final Enum<?>[] enums =  (Enum<?>[])field.getType().getEnumConstants();
+                for (final Enum<?> e : enums) {
+                    if ((enumType == EnumType.STRING && e.name().equalsIgnoreCase(rs.getString(index))) ||
+                            (enumType == EnumType.ORDINAL && e.ordinal() == rs.getInt(index))) {
+                        field.set(entity, e);
+                        return;
+                    }
+                }
+            } else if (type == int.class) {
+                field.set(entity, rs.getInt(index));
+            } else if (type == Integer.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getInt(index));
+                }
+            } else if (type == Date.class) {
+                final Object data = rs.getDate(index);
+                if (data == null) {
+                    field.set(entity, null);
+                    return;
+                }
+                field.set(entity, DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
+            } else if (type == Calendar.class) {
+                final Object data = rs.getDate(index);
+                if (data == null) {
+                    field.set(entity, null);
+                    return;
+                }
+                final Calendar cal = Calendar.getInstance();
+                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
+                field.set(entity, cal);
+            } else if (type == boolean.class) {
+                field.setBoolean(entity, rs.getBoolean(index));
+            } else if (type == Boolean.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getBoolean(index));
+                }
+            } else if (type == URI.class) {
+                try {
+                    String str = rs.getString(index);
+                    field.set(entity, str == null ? null : new URI(str));
+                } catch (URISyntaxException e) {
+                    throw new CloudRuntimeException("Invalid URI: " + rs.getString(index), e);
+                }
+            } else if (type == URL.class) {
+                try {
+                    String str = rs.getString(index);
+                    field.set(entity, str != null ? new URL(str) : null);
+                } catch (MalformedURLException e) {
+                    throw new CloudRuntimeException("Invalid URL: " + rs.getString(index), e);
+                }
+            } else if (type == Ip.class) {
+                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
+                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
+
+                Ip ip = null;
+                if (enumType == EnumType.STRING) {
+                    String s = rs.getString(index);
+                    ip = s == null ? null : new Ip(NetUtils.ip2Long(s));
+                } else {
+                    ip = new Ip(rs.getLong(index));
+                }
+                field.set(entity, ip);
+            } else if (type == short.class) {
+                field.setShort(entity, rs.getShort(index));
+            } else if (type == Short.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getShort(index));
+                }
+            } else if (type == float.class) {
+                field.setFloat(entity, rs.getFloat(index));
+            } else if (type == Float.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getFloat(index));
+                }
+            } else if (type == double.class) {
+                field.setDouble(entity, rs.getDouble(index));
+            } else if (type == Double.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getDouble(index));
+                }
+            } else if (type == byte.class) {
+                field.setByte(entity, rs.getByte(index));
+            } else if (type == Byte.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getByte(index));
+                }
+            } else if (type == byte[].class) {
+                field.set(entity, rs.getBytes(index));
+            } else {
+                field.set(entity, rs.getObject(index));
+            }
+        } catch (final IllegalAccessException e) {
+            throw new CloudRuntimeException("Yikes! ", e);
+        }
+    }
+
+    @DB(txn=false) @SuppressWarnings("unchecked")
+    protected <M> M getObject(Class<M> type, ResultSet rs, int index) throws SQLException {
+        if (type == String.class) {
+            byte[] bytes = rs.getBytes(index);
+            if(bytes != null) {
+                try {
+                    return (M)new String(bytes, "UTF-8");
+                } catch (UnsupportedEncodingException e) {
+                    throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data");
+                }
+            } else {
+                return null;
+            }
+        } else if (type == int.class) {
+            return (M)new Integer(rs.getInt(index));
+        } else if (type == Integer.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M)new Integer(rs.getInt(index));
+            }
+        } else if (type == long.class) {
+            return (M)new Long(rs.getLong(index));
+        } else if (type == Long.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M)new Long(rs.getLong(index));
+            }
+        } else if (type == Date.class) {
+            final Object data = rs.getDate(index);
+            if (data == null) {
+                return null;
+            } else {
+                return (M)DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index));
+            }
+        } else if (type == short.class) {
+            return (M)new Short(rs.getShort(index));
+        } else if (type == Short.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M)new Short(rs.getShort(index));
+            }
+        } else if (type == boolean.class) {
+            return (M)new Boolean(rs.getBoolean(index));
+        } else if (type == Boolean.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M)new Boolean(rs.getBoolean(index));
+            }
+        } else if (type == float.class) {
+            return (M)new Float(rs.getFloat(index));
+        } else if (type == Float.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M)new Float(rs.getFloat(index));
+            }
+        } else if (type == double.class) {
+            return (M)new Double(rs.getDouble(index));
+        } else if (type == Double.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M)new Double(rs.getDouble(index));
+            }
+        } else if (type == byte.class) {
+            return (M)new Byte(rs.getByte(index));
+        } else if (type == Byte.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M)new Byte(rs.getByte(index));
+            }
+        } else if (type == Calendar.class) {
+            final Object data = rs.getDate(index);
+            if (data == null) {
+                return null;
+            } else {
+                final Calendar cal = Calendar.getInstance();
+                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
+                return (M)cal;
+            }
+        } else if (type == byte[].class) {
+            return (M)rs.getBytes(index);
+        } else {
+            return (M)rs.getObject(index);
+        }
+    }
+
+    @DB(txn=false)
+    protected int addJoinAttributes(int count, PreparedStatement pstmt, Collection<JoinBuilder<SearchCriteria<?>>> joins) throws SQLException {
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            for (final Pair<Attribute, Object> value : join.getT().getValues()) {
+                prepareAttribute(++count, pstmt, value.first(), value.second());
+            }
+        }
+
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            if (join.getT().getJoins() != null) {
+                count = addJoinAttributes(count, pstmt, join.getT().getJoins());
+            }
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("join search statement is " + pstmt);
+        }
+        return count;
+    }
+
+    protected int update(ID id, UpdateBuilder ub, T entity) {
+        if (_cache != null) {
+            _cache.remove(id);
+        }
+        SearchCriteria<T> sc = createSearchCriteria();
+        sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+
+        try {
+            if (ub.getCollectionChanges() != null) {
+                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ub.getCollectionChanges());
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to persist element collection", e);
+        }
+
+        int rowsUpdated = update(ub, sc, null);
+
+        txn.commit();
+
+        return rowsUpdated;
+    }
+
+    public int update(UpdateBuilder ub, final SearchCriteria<?> sc, Integer rows) {
+        StringBuilder sql = null;
+        PreparedStatement pstmt = null;
+        final Transaction txn = Transaction.currentTxn();
+        try {
+            final String searchClause = sc.getWhereClause();
+
+            sql = ub.toSql(_tables);
+            if (sql == null) {
+                return  0;
+            }
+
+            sql.append(searchClause);
+
+            if (rows != null) {
+                sql.append(" LIMIT ").append(rows);
+            }
+
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+            Collection<Ternary<Attribute, Boolean, Object>> changes = ub.getChanges();
+
+            int i = 1;
+            for (final Ternary<Attribute, Boolean, Object> value : changes) {
+                prepareAttribute(i++, pstmt, value.first(), value.third());
+            }
+
+            for (Pair<Attribute, Object> value : sc.getValues()) {
+                prepareAttribute(i++, pstmt, value.first(), value.second());
+            }
+
+            int result = pstmt.executeUpdate();
+            txn.commit();
+            ub.clear();
+            return result;
+        } catch (final SQLException e) {
+            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
+                throw new EntityExistsException("Entity already exists ", e);
+            }
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    @DB(txn=false)
+    protected Attribute findAttributeByFieldName(String name) {
+        return _allAttributes.get(name);
+    }
+
+    @DB(txn=false)
+    protected String buildSelectByIdSql(final StringBuilder sql) {
+        if (_idField == null) {
+            return null;
+        }
+
+        if (_idField.getAnnotation(EmbeddedId.class) == null) {
+            sql.append(_table).append(".").append(DbUtil.getColumnName(_idField, null)).append(" = ? ");
+        } else {
+            final Class<?> clazz = _idField.getClass();
+            final AttributeOverride[] overrides = DbUtil.getAttributeOverrides(_idField);
+            for (final Field field : clazz.getDeclaredFields()) {
+                sql.append(_table).append(".").append(DbUtil.getColumnName(field, overrides)).append(" = ? AND ");
+            }
+            sql.delete(sql.length() - 4, sql.length());
+        }
+
+        return sql.toString();
+    }
+
+    @DB(txn=false)
+    @Override
+    public Class<T> getEntityBeanType() {
+        return _entityBeanType;
+    }
+
+    @DB(txn=false)
+    protected T findOneIncludingRemovedBy(final SearchCriteria<T> sc) {
+        Filter filter = new Filter(1);
+        List<T> results = searchIncludingRemoved(sc, filter, null, false);
+        assert results.size() <= 1 : "Didn't the limiting worked?";
+        return results.size() == 0 ? null : results.get(0);
+    }
+
+    @Override
+    @DB(txn=false)
+    public T findOneBy(final SearchCriteria<T> sc) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @DB(txn=false)
+    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return listIncludingRemovedBy(sc, filter);
+    }
+
+    @DB(txn=false)
+    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter, final boolean enable_query_cache) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return listIncludingRemovedBy(sc, filter, enable_query_cache);
+    }
+
+    @DB(txn=false)
+    protected List<T> listBy(final SearchCriteria<T> sc) {
+        return listBy(sc, null);
+    }
+
+    @DB(txn=false)
+    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter, final boolean enable_query_cache) {
+        return searchIncludingRemoved(sc, filter, null, false, enable_query_cache);
+    }
+
+    @DB(txn=false)
+    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter) {
+        return searchIncludingRemoved(sc, filter, null, false);
+    }
+
+    @DB(txn=false)
+    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc) {
+        return listIncludingRemovedBy(sc, null);
+    }
+
+    @Override @DB(txn=false)
+    @SuppressWarnings("unchecked")
+    public T findById(final ID id) {
+        if (_cache != null) {
+            final Element element = _cache.get(id);
+            return element == null ? lockRow(id, null) : (T)element.getObjectValue();
+        } else {
+            return lockRow(id, null);
+        }
+    }
+
+    @Override @DB(txn=false)
+    @SuppressWarnings("unchecked")
+    public T findByUuid(final String uuid) {
+        SearchCriteria<T> sc = createSearchCriteria();
+        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
+        return findOneBy(sc);
+    }
+
+    @Override @DB(txn=false)
+    @SuppressWarnings("unchecked")
+    public T findByUuidIncludingRemoved(final String uuid) {
+        SearchCriteria<T> sc = createSearchCriteria();
+        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override @DB(txn=false)
+    public T findByIdIncludingRemoved(ID id) {
+        return findById(id, true, null);
+    }
+
+    @Override @DB(txn=false)
+    public T findById(final ID id, boolean fresh) {
+        if(!fresh) {
+            return findById(id);
+        }
+
+        if (_cache != null) {
+            _cache.remove(id);
+        }
+        return lockRow(id, null);
+    }
+
+    @Override @DB(txn=false)
+    public T lockRow(ID id, Boolean lock) {
+        return findById(id, false, lock);
+    }
+
+    protected T findById(ID id, boolean removed, Boolean lock) {
+        StringBuilder sql = new StringBuilder(_selectByIdSql);
+        if (!removed && _removed != null) {
+            sql.append(" AND ").append(_removed.first());
+        }
+        if (lock != null) {
+            sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
+        }
+        Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+            if (_idField.getAnnotation(EmbeddedId.class) == null) {
+                prepareAttribute(1, pstmt, _idAttributes.get(_table)[0], id);
+            }
+
+            ResultSet rs = pstmt.executeQuery();
+            return rs.next() ? toEntityBean(rs, true) : null;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    @Override @DB(txn=false)
+    public T acquireInLockTable(ID id) {
+        return acquireInLockTable(id, _timeoutSeconds);
+    }
+
+    @Override
+    public T acquireInLockTable(final ID id, int seconds) {
+        Transaction txn = Transaction.currentTxn();
+        T t = null;
+        boolean locked  = false;
+        try {
+            if (!txn.lock(_table + id.toString(), seconds)) {
+                return null;
+            }
+
+            locked = true;
+            t = findById(id);
+            return t;
+        } finally {
+            if (t == null && locked) {
+                txn.release(_table + id.toString());
+            }
+        }
+    }
+
+    @Override
+    public boolean releaseFromLockTable(final ID id) {
+        final Transaction txn = Transaction.currentTxn();
+        return txn.release(_table + id);
+    }
+
+    @Override @DB(txn=false)
+    public boolean lockInLockTable(final String id) {
+        return lockInLockTable(id, _timeoutSeconds);
+    }
+
+    @Override
+    public boolean lockInLockTable(final String id, int seconds) {
+        Transaction txn = Transaction.currentTxn();
+        return txn.lock(_table + id, seconds);
+    }
+
+    @Override
+    public boolean unlockFromLockTable(final String id) {
+        final Transaction txn = Transaction.currentTxn();
+        return txn.release(_table + id);
+    }
+
+    @Override @DB(txn=false)
+    public List<T> listAllIncludingRemoved() {
+        return listAllIncludingRemoved(null);
+    }
+
+    @DB(txn=false)
+    protected List<Object> addGroupBy(final StringBuilder sql, SearchCriteria<?> sc) {
+        Pair<GroupBy<?, ?>, List<Object>> groupBys = sc.getGroupBy();
+        if (groupBys != null) {
+            groupBys.first().toSql(sql);
+            return groupBys.second();
+        } else {
+            return null;
+        }
+    }
+
+    @DB(txn=false)
+    protected void addFilter(final StringBuilder sql, final Filter filter) {
+        if (filter != null) {
+            if (filter.getOrderBy() != null) {
+                sql.append(filter.getOrderBy());
+            }
+            if (filter.getOffset() != null) {
+                sql.append(" LIMIT ");
+                sql.append(filter.getOffset());
+                if (filter.getLimit() != null) {
+                    sql.append(", ").append(filter.getLimit());
+                }
+            }
+        }
+    }
+
+    @Override @DB(txn=false)
+    public List<T> listAllIncludingRemoved(final Filter filter) {
+        final StringBuilder sql = createPartialSelectSql(null, false);
+        addFilter(sql, filter);
+
+        return executeList(sql.toString());
+    }
+
+    protected List<T> executeList(final String sql, final Object... params) {
+        final Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        final List<T> result = new ArrayList<T>();
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            for (final Object param : params) {
+                pstmt.setObject(++i, param);
+            }
+
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(toEntityBean(rs, true));
+            }
+            return result;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @Override @DB(txn=false)
+    public List<T> listAll() {
+        return listAll(null);
+    }
+
+    @Override @DB(txn=false)
+    public List<T> listAll(final Filter filter) {
+        if (_removed == null) {
+            return listAllIncludingRemoved(filter);
+        }
+
+        final StringBuilder sql = createPartialSelectSql(null, true);
+        sql.append(_removed.first());
+        addFilter(sql, filter);
+
+        return executeList(sql.toString());
+    }
+
+    @Override
+    public boolean expunge(final ID id) {
+        final Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = null;
+        try {
+            txn.start();
+            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
+                sql = deletSql.first();
+                final Attribute[] attrs = deletSql.second();
+
+                pstmt = txn.prepareAutoCloseStatement(sql);
+
+                for (int i = 0; i < attrs.length; i++) {
+                    prepareAttribute(i + 1, pstmt, attrs[i], id);
+                }
+                pstmt.executeUpdate();
+            }
+
+            txn.commit();
+            if (_cache != null) {
+                _cache.remove(id);
+            }
+            return true;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    // FIXME: Does not work for joins.
+    @Override
+    public int expunge(final SearchCriteria<T> sc) {
+        final StringBuilder str = new StringBuilder("DELETE FROM ");
+        str.append(_table);
+        str.append(" WHERE ");
+
+        if (sc != null && sc.getWhereClause().length() > 0) {
+            str.append(sc.getWhereClause());
+        }
+
+        final String sql = str.toString();
+
+        final Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            for (final Pair<Attribute, Object> value : sc.getValues()) {
+                prepareAttribute(++i, pstmt, value.first(), value.second());
+            }
+            return pstmt.executeUpdate();
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @DB(txn=false)
+    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause, final boolean enable_query_cache) {
+        StringBuilder sql = new StringBuilder(enable_query_cache ? _partialQueryCacheSelectSql.first() : _partialSelectSql.first());
+        if (sc != null && !sc.isSelectAll()) {
+            sql.delete(7, sql.indexOf(" FROM"));
+            sc.getSelect(sql, 7);
+        }
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+
+    @DB(txn=false)
+    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause) {
+        StringBuilder sql = new StringBuilder(_partialSelectSql.first());
+        if (sc != null && !sc.isSelectAll()) {
+            sql.delete(7, sql.indexOf(" FROM"));
+            sc.getSelect(sql, 7);
+        }
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+
+
+    @DB(txn = false)
+    protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
+        int fromIndex = str.lastIndexOf("WHERE");
+        if (fromIndex == -1) {
+            fromIndex = str.length();
+            str.append(" WHERE ");
+        } else {
+            str.append(" AND ");
+        }
+
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            StringBuilder onClause = new StringBuilder();
+            onClause.append(" ").append(join.getType().getName()).append(" ").append(join.getSecondAttribute().table)
+            .append(" ON ").append(join.getFirstAttribute().table).append(".").append(join.getFirstAttribute().columnName)
+            .append("=").append(join.getSecondAttribute().table).append(".").append(join.getSecondAttribute().columnName)
+            .append(" ");
+            str.insert(fromIndex, onClause);
+            String whereClause = join.getT().getWhereClause();
+            if ((whereClause != null) && !"".equals(whereClause)) {
+                str.append(" (").append(whereClause).append(") AND");
+            }
+            fromIndex += onClause.length();
+        }
+
+        str.delete(str.length() - 4, str.length());
+
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            if (join.getT().getJoins() != null) {
+                addJoins(str, join.getT().getJoins());
+            }
+        }
+    }
+
+    @Override @DB(txn=false)
+    public List<T> search(final SearchCriteria<T> sc, final Filter filter) {
+        return search(sc, filter, null, false);
+    }
+
+    @Override @DB(txn=false)
+    public Pair<List<T>, Integer> searchAndCount(final SearchCriteria<T> sc, final Filter filter) {
+        List<T> objects = search(sc, filter, null, false);
+        Integer count = getCount(sc);
+        return new Pair<List<T>, Integer>(objects, count);
+    }
+
+    @Override @DB(txn=false)
+    public List<T> search(final SearchCriteria<T> sc, final Filter filter, final boolean enable_query_cache) {
+        return search(sc, filter, null, false, enable_query_cache);
+    }
+
+    @Override @DB(txn=false)
+    public boolean update(ID id, T entity) {
+        assert Enhancer.isEnhanced(entity.getClass()) : "Entity is not generated by this dao";
+
+        UpdateBuilder ub = getUpdateBuilder(entity);
+        boolean result = update(id, ub, entity) != 0;
+        return result;
+    }
+
+    @DB(txn=false)
+    public int update(final T entity, final SearchCriteria<T> sc, Integer rows) {
+        final UpdateBuilder ub = getUpdateBuilder(entity);
+        return update(ub, sc, rows);
+    }
+
+    @DB(txn=false)
+    public int update(final T entity, final SearchCriteria<T> sc) {
+        final UpdateBuilder ub = getUpdateBuilder(entity);
+        return update(ub, sc, null);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T persist(final T entity) {
+        if (Enhancer.isEnhanced(entity.getClass())) {
+            if (_idField != null) {
+                ID id;
+                try {
+                    id = (ID)_idField.get(entity);
+                } catch (IllegalAccessException e) {
+                    throw new CloudRuntimeException("How can it be illegal access...come on", e);
+                }
+                update(id, entity);
+                return entity;
+            }
+
+            assert false : "Can't call persit if you don't have primary key";
+        }
+
+        ID id = null;
+        final Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = null;
+        try {
+            txn.start();
+            for (final Pair<String, Attribute[]> pair : _insertSqls) {
+                sql = pair.first();
+                final Attribute[] attrs = pair.second();
+
+                pstmt = txn.prepareAutoCloseStatement(sql, Statement.RETURN_GENERATED_KEYS);
+
+                int index = 1;
+                index = prepareAttributes(pstmt, entity, attrs, index);
+
+                pstmt.executeUpdate();
+
+                final ResultSet rs = pstmt.getGeneratedKeys();
+                if (id == null) {
+                    if (rs != null && rs.next()) {
+                        id = (ID)rs.getObject(1);
+                    }
+                    try {
+                        if (_idField != null) {
+                            if (id != null) {
+                                _idField.set(entity, id);
+                            } else {
+                                id = (ID)_idField.get(entity);
+                            }
+                        }
+                    } catch (final IllegalAccessException e) {
+                        throw new CloudRuntimeException("Yikes! ", e);
+                    }
+                }
+            }
+
+            if (_ecAttributes != null && _ecAttributes.size() > 0) {
+                HashMap<Attribute, Object> ecAttributes = new HashMap<Attribute, Object>();
+                for (Attribute attr : _ecAttributes) {
+                    Object ec = attr.field.get(entity);
+                    if (ec != null) {
+                        ecAttributes.put(attr, ec);
+                    }
+                }
+
+                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ecAttributes);
+            }
+            txn.commit();
+        } catch (final SQLException e) {
+            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
+                throw new EntityExistsException("Entity already exists: ", e);
+            } else {
+                throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+            }
+        } catch (IllegalArgumentException e) {
+            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
+        } catch (IllegalAccessException e) {
+            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
+        }
+
+        return _idField != null ? findByIdIncludingRemoved(id) : null;
+    }
+
+    protected void insertElementCollection(T entity, Attribute idAttribute, ID id, Map<Attribute, Object> ecAttributes) throws SQLException {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        for (Map.Entry<Attribute, Object> entry : ecAttributes.entrySet()) {
+            Attribute attr = entry.getKey();
+            Object obj = entry.getValue();
+
+            EcInfo ec = (EcInfo)attr.attache;
+            Enumeration en = null;
+            if (ec.rawClass == null) {
+                en = Collections.enumeration(Arrays.asList((Object[])obj));
+            } else {
+                en = Collections.enumeration((Collection)obj);
+            }
+            PreparedStatement pstmt = txn.prepareAutoCloseStatement(ec.clearSql);
+            prepareAttribute(1, pstmt, idAttribute, id);
+            pstmt.executeUpdate();
+
+            while (en.hasMoreElements()) {
+                pstmt = txn.prepareAutoCloseStatement(ec.insertSql);
+                if (ec.targetClass == Date.class) {
+                    pstmt.setString(1, DateUtil.getDateDisplayString(s_gmtTimeZone, (Date)en.nextElement()));
+                } else {
+                    pstmt.setObject(1, en.nextElement());
+                }
+                prepareAttribute(2, pstmt, idAttribute, id);
+                pstmt.executeUpdate();
+            }
+        }
+        txn.commit();
+    }
+
+    @DB(txn=false)
+    protected Object generateValue(final Attribute attr) {
+        if (attr.is(Attribute.Flag.Created) || attr.is(Attribute.Flag.Removed)) {
+            return new Date();
+        } else if (attr.is(Attribute.Flag.TableGV)) {
+            return null;
+            // Not sure what to do here.
+        } else if (attr.is(Attribute.Flag.AutoGV)) {
+            if (attr.columnName.equals(GenericDao.XID_COLUMN)) {
+                return UUID.randomUUID().toString();
+            }
+            assert (false) : "Auto generation is not supported.";
+            return null;
+        } else if (attr.is(Attribute.Flag.SequenceGV)) {
+            assert (false) : "Sequence generation is not supported.";
+            return null;
+        } else if (attr.is(Attribute.Flag.DC)) {
+            return _discriminatorValues.get(attr.columnName);
+        } else {
+            assert (false) : "Attribute can't be auto generated: " + attr.columnName;
+            return null;
+        }
+    }
+
+    @DB(txn=false)
+    protected void prepareAttribute(final int j, final PreparedStatement pstmt, final Attribute attr, Object value) throws SQLException {
+        if (attr.is(Attribute.Flag.DaoGenerated) && value == null) {
+            value = generateValue(attr);
+            if (attr.field == null) {
+                pstmt.setObject(j, value);
+                return;
+            }
+        }
+        if (attr.field.getType() == String.class) {
+            final String str = (String)value;
+            if (str == null) {
+                pstmt.setString(j, null);
+                return;
+            }
+            final Column column = attr.field.getAnnotation(Column.class);
+            final int length = column != null ? column.length() : 255;
+
+            // to support generic localization, utilize MySql UTF-8 support
+            if (length < str.length()) {
+                try {
+                    if (attr.is(Attribute.Flag.Encrypted)){
+                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str.substring(0, column.length())).getBytes("UTF-8"));
+                    } else {
+                        pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8"));
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    // no-way it can't support UTF-8 encoding
+                    assert(false);
+                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
+                }
+            } else {
+                try {
+                    if (attr.is(Attribute.Flag.Encrypted)){
+                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str).getBytes("UTF-8"));
+                    } else {
+                        pstmt.setBytes(j, str.getBytes("UTF-8"));
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    // no-way it can't support UTF-8 encoding
+                    assert(false);
+                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
+                }
+            }
+        } else if (attr.field.getType() == Date.class) {
+            final Date date = (Date)value;
+            if (date == null) {
+                pstmt.setObject(j, null);
+                return;
+            }
+            if (attr.is(Attribute.Flag.Date)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
+            } else if (attr.is(Attribute.Flag.TimeStamp)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
+            } else if (attr.is(Attribute.Flag.Time)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
+            }
+        } else if (attr.field.getType() == Calendar.class) {
+            final Calendar cal = (Calendar)value;
+            if (cal == null) {
+                pstmt.setObject(j, null);
+                return;
+            }
+            if (attr.is(Attribute.Flag.Date)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
+            } else if (attr.is(Attribute.Flag.TimeStamp)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
+            } else if (attr.is(Attribute.Flag.Time)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
+            }
+        } else if (attr.field.getType().isEnum()) {
+            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
+            final EnumType type = (enumerated == null) ? EnumType.STRING : enumerated.value();
+            if (type == EnumType.STRING) {
+                pstmt.setString(j, value == null ? null :  value.toString());
+            } else if (type == EnumType.ORDINAL) {
+                if (value == null) {
+                    pstmt.setObject(j, null);
+                } else {
+                    pstmt.setInt(j, ((Enum<?>)value).ordinal());
+                }
+            }
+        } else if (attr.field.getType() == URI.class) {
+            pstmt.setString(j, value == null ? null : value.toString());
+        } else if (attr.field.getType() == URL.class) {
+            pstmt.setURL(j, (URL)value);
+        } else if (attr.field.getType() == byte[].class) {
+            pstmt.setBytes(j, (byte[])value);
+        } else if (attr.field.getType() == Ip.class) {
+            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
+            final EnumType type = (enumerated == null) ? EnumType.ORDINAL : enumerated.value();
+            if (type == EnumType.STRING) {
+                pstmt.setString(j, value == null ? null : value.toString());
+            } else if (type == EnumType.ORDINAL) {
+                if (value == null) {
+                    pstmt.setObject(j, null);
+                } else {
+                    pstmt.setLong(j, (value instanceof Ip) ? ((Ip)value).longValue() : NetUtils.ip2Long((String)value));
+                }
+            }
+        } else {
+            pstmt.setObject(j, value);
+        }
+    }
+
+    @DB(txn=false)
+    protected int prepareAttributes(final PreparedStatement pstmt, final Object entity, final Attribute[] attrs, final int index) throws SQLException {
+        int j = 0;
+        for (int i = 0; i < attrs.length; i++) {
+            j = i + index;
+            try {
+                prepareAttribute(j, pstmt, attrs[i], attrs[i].field != null ? attrs[i].field.get(entity) : null);
+            } catch (final IllegalArgumentException e) {
+                throw new CloudRuntimeException("IllegalArgumentException", e);
+            } catch (final IllegalAccessException e) {
+                throw new CloudRuntimeException("IllegalArgumentException", e);
+            }
+        }
+
+        return j;
+    }
+
+    @SuppressWarnings("unchecked") @DB(txn=false)
+    protected T toEntityBean(final ResultSet result, final boolean cache) throws SQLException {
+        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
+
+        toEntityBean(result, entity);
+
+        if (cache && _cache != null) {
+            try {
+                _cache.put(new Element(_idField.get(entity), entity));
+            } catch (final Exception e) {
+                s_logger.debug("Can't put it in the cache", e);
+            }
+        }
+
+        return entity;
+    }
+
+    @DB(txn=false)
+    protected T toVO(ResultSet result, boolean cache) throws SQLException {
+        T entity;
+        try {
+            entity = _entityBeanType.newInstance();
+        } catch (InstantiationException e1) {
+            throw new CloudRuntimeException("Unable to instantiate entity", e1);
+        } catch (IllegalAccessException e1) {
+            throw new CloudRuntimeException("Illegal Access", e1);
+        }
+        toEntityBean(result, entity);
+        if (cache && _cache != null) {
+            try {
+                _cache.put(new Element(_idField.get(entity), entity));
+            } catch (final Exception e) {
+                s_logger.debug("Can't put it in the cache", e);
+            }
+        }
+
+        return entity;
+    }
+
+    @DB(txn=false)
+    protected void toEntityBean(final ResultSet result, final T entity) throws SQLException {
+        ResultSetMetaData meta = result.getMetaData();
+        for (int index = 1, max = meta.getColumnCount(); index <= max; index++) {
+            setField(entity, result, meta, index);
+        }
+        for (Attribute attr : _ecAttributes) {
+            loadCollection(entity, attr);
+        }
+    }
+
+    @DB(txn = true)
+    @SuppressWarnings("unchecked")
+    protected void loadCollection(T entity, Attribute attr)  {
+        EcInfo ec = (EcInfo)attr.attache;
+
+        Transaction txn = Transaction.currentTxn();
+        ResultSet rs = null;
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareStatement(ec.selectSql);
+            pstmt.setObject(1, _idField.get(entity));
+            rs = pstmt.executeQuery();
+            ArrayList lst = new ArrayList();
+            if (ec.targetClass == Integer.class) {
+                while (rs.next()) {
+                    lst.add(rs.getInt(1));
+                }
+            } else if (ec.targetClass == Long.class) {
+                while (rs.next()) {
+                    lst.add(rs.getLong(1));
+                }
+            } else if (ec.targetClass == String.class) {
+                while (rs.next()) {
+                    lst.add(rs.getString(1));
+                }
+            } else if (ec.targetClass == Short.class) {
+                while (rs.next()) {
+                    lst.add(rs.getShort(1));
+                }
+            } else if (ec.targetClass == Date.class) {
+                while (rs.next()) {
+                    lst.add(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(1)));
+                }
+            } else if (ec.targetClass == Boolean.class) {
+                while (rs.next()) {
+                    lst.add(rs.getBoolean(1));
+                }
+            } else {
+                assert (false) : "You'll need to add more classeses";
+            }
+
+            if (ec.rawClass == null) {
+                Object[] array = (Object[])Array.newInstance(ec.targetClass);
+                lst.toArray(array);
+                try {
+                    attr.field.set(entity, array);
+                } catch (IllegalArgumentException e) {
+                    throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
+                } catch (IllegalAccessException e) {
+                    throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
+                }
+            } else {
+                try {
+                    Collection coll = (Collection)ec.rawClass.newInstance();
+                    coll.addAll(lst);
+                    attr.field.set(entity, coll);
+                } catch (IllegalAccessException e) {
+                    throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
+                } catch (InstantiationException e) {
+                    throw new CloudRuntimeException("Never should happen", e);
+                }
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Error executing " + pstmt, e);
+        } catch (IllegalArgumentException e) {
+            throw new CloudRuntimeException("Error executing " + pstmt, e);
+        } catch (IllegalAccessException e) {
+            throw new CloudRuntimeException("Error executing " + pstmt, e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+                s_logger.error("Why are we getting an exception at close? ", e);
+            }
+        }
+    }
+
+    @Override
+    public void expunge() {
+        if (_removed == null) {
+            return;
+        }
+        final StringBuilder sql = new StringBuilder("DELETE FROM ");
+        sql.append(_table).append(" WHERE ").append(_removed.first()).append(" IS NOT NULL");
+        final Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on " + pstmt, e);
+        }
+    }
+
+    @DB(txn=false)
+    protected void setField(final Object entity, final ResultSet rs, ResultSetMetaData meta, final int index) throws SQLException {
+        Attribute attr = _allColumns.get(new Pair<String, String>(meta.getTableName(index), meta.getColumnName(index)));
+        if ( attr == null ){
+            // work around for mysql bug to return original table name instead of view name in db view case
+            Table tbl = entity.getClass().getSuperclass().getAnnotation(Table.class);
+            if ( tbl != null ){
+                attr = _allColumns.get(new Pair<String, String>(tbl.name(), meta.getColumnLabel(index)));
+            }
+        }
+        assert (attr != null) : "How come I can't find " + meta.getCatalogName(index) + "." + meta.getColumnName(index);
+        setField(entity, attr.field, rs, index);
+    }
+
+    @Override
+    public boolean remove(final ID id) {
+        if (_removeSql == null) {
+            return expunge(id);
+        }
+
+        final Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(_removeSql.first());
+            final Attribute[] attrs = _removeSql.second();
+            prepareAttribute(1, pstmt, attrs[attrs.length - 1], null);
+            for (int i = 0; i < attrs.length - 1; i++) {
+                prepareAttribute(i + 2, pstmt, attrs[i], id);
+            }
+
+            final int result = pstmt.executeUpdate();
+            txn.commit();
+            if (_cache != null) {
+                _cache.remove(id);
+            }
+            return result > 0;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    @Override
+    public int remove(SearchCriteria<T> sc) {
+        if (_removeSql == null) {
+            return expunge(sc);
+        }
+
+        T vo = createForUpdate();
+        UpdateBuilder ub = getUpdateBuilder(vo);
+
+        ub.set(vo, _removed.second(), new Date());
+        return update(ub, sc, null);
+    }
+
+    protected Cache _cache;
+    @DB(txn=false)
+    protected void createCache(final Map<String, ? extends Object> params) {
+        final String value = (String)params.get("cache.size");
+
+        if (value != null) {
+            final CacheManager cm = CacheManager.create();
+            final int maxElements = NumbersUtil.parseInt(value, 0);
+            final int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300);
+            final int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300);
+            _cache = new Cache(getName(), maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle);
+            cm.addCache(_cache);
+            s_logger.info("Cache created: " + _cache.toString());
+        } else {
+            _cache = null;
+        }
+    }
+
+    @Override @DB(txn=false)
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+
+        final String value = (String)params.get("lock.timeout");
+        _timeoutSeconds = NumbersUtil.parseInt(value, 300);
+
+        createCache(params);
+        final boolean load = Boolean.parseBoolean((String)params.get("cache.preload"));
+        if (load) {
+            listAll();
+        }
+
+        return true;
+    }
+
+    @DB(txn=false)
+    public static <T> UpdateBuilder getUpdateBuilder(final T entityObject) {
+        final Factory factory = (Factory)entityObject;
+        assert(factory != null);
+        return (UpdateBuilder)factory.getCallback(1);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override @DB(txn=false)
+    public SearchBuilder<T> createSearchBuilder() {
+        final T entity = (T)_searchEnhancer.create();
+        final Factory factory = (Factory)entity;
+        SearchBuilder<T> builder = new SearchBuilder<T>(entity, _allAttributes);
+        factory.setCallback(0, builder);
+        return builder;
+    }
+
+    @Override @DB(txn=false)
+    public SearchCriteria<T> createSearchCriteria() {
+        SearchBuilder<T> builder = createSearchBuilder();
+        return builder.create();
+    }
+
+    @Override @DB(txn=false)
+    public <K> SearchCriteria2 createSearchCriteria2(Class<K> resultType) {
+        final T entity = (T)_searchEnhancer.create();
+        final Factory factory = (Factory)entity;
+        SearchCriteria2 sc = new SearchCriteria2(entity, resultType, _allAttributes, this);
+        factory.setCallback(0, sc);
+        return sc;
+    }
+
+    @Override @DB(txn=false)
+    public SearchCriteria2 createSearchCriteria2() {
+        final T entity = (T)_searchEnhancer.create();
+        final Factory factory = (Factory)entity;
+        SearchCriteria2 sc = new SearchCriteria2(entity, entity.getClass(), _allAttributes, this);
+        factory.setCallback(0, sc);
+        return sc;
+    }
+
+    @Override
+    public int getRegionId(){
+    	return Transaction.s_region_id;
+    }
+
+    public Integer getCount(SearchCriteria<T> sc) {
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createCountSelect(sc, clause != null);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        // we have to disable group by in getting count, since count for groupBy clause will be different.
+        //List<Object> groupByValues = addGroupBy(str, sc);
+        final Transaction txn = Transaction.currentTxn();
+        final String sql = str.toString();
+
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(++i, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            /*
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+             */
+
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                return rs.getInt(1);
+            }
+            return 0;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @DB(txn=false)
+    protected StringBuilder createCountSelect(SearchCriteria<?> sc, final boolean whereClause) {
+        StringBuilder sql = new StringBuilder(_count);
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+}


[07/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/SearchCriteriaService.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SearchCriteriaService.java b/framework/db/src/com/cloud/utils/db/SearchCriteriaService.java
new file mode 100755
index 0000000..2947255
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/SearchCriteriaService.java
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.util.List;
+
+import com.cloud.utils.db.SearchCriteria.Op;
+
+public interface SearchCriteriaService<T, K> {
+	public void selectField(Object... useless);
+	public void addAnd(Object useless, Op op, Object...values);
+	public List<K> list();
+	public T getEntity();
+	public <K> K find();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/SequenceFetcher.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SequenceFetcher.java b/framework/db/src/com/cloud/utils/db/SequenceFetcher.java
new file mode 100644
index 0000000..8823552
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/SequenceFetcher.java
@@ -0,0 +1,171 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.persistence.TableGenerator;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.concurrency.NamedThreadFactory;
+
+/**
+ * Since Mysql does not have sequence support, we have
+ * table retrieval was inside a transaction, the value
+ * gets locked until the transaction is over.
+ * 
+ * allocation size.
+ *
+ */
+public class SequenceFetcher {
+    private final static Logger s_logger = Logger.getLogger(SequenceFetcher.class);
+    ExecutorService _executors;
+    private final static Random random = new Random();
+    
+    public <T> T getNextSequence(Class<T> clazz, TableGenerator tg) {
+        return getNextSequence(clazz, tg, null, false);
+    }
+    
+    public <T> T getNextSequence(Class<T> clazz, TableGenerator tg, Object key) {
+    	return getNextSequence(clazz, tg, key, false);
+    }
+    
+    public <T> T getRandomNextSequence(Class<T> clazz, TableGenerator tg) {
+        return getNextSequence(clazz, tg, null, true);
+    }
+    
+    public <T> T getNextSequence(Class<T> clazz, TableGenerator tg, Object key, boolean isRandom) {
+        Future<T> future = _executors.submit(new Fetcher<T>(clazz, tg, key, isRandom));
+        try {
+            return future.get();
+        } catch (Exception e) {
+            s_logger.warn("Unable to get sequeunce for " + tg.table() + ":" + tg.pkColumnValue(), e);
+            return null;
+        }
+    }
+    
+    protected SequenceFetcher() {
+        _executors = new ThreadPoolExecutor(100, 100, 120l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(250), new NamedThreadFactory("SequenceFetcher"));
+    }
+
+    protected static final SequenceFetcher s_instance = new SequenceFetcher();
+    public static SequenceFetcher getInstance() {
+        return s_instance;
+    }
+    
+    protected class Fetcher<T> implements Callable<T> {
+        TableGenerator _tg;
+        Class<T> _clazz;
+        Object _key;
+        boolean isRandom = false;
+        
+        protected Fetcher(Class<T> clazz, TableGenerator tg, Object key, boolean isRandom) {
+            _tg = tg;
+            _clazz = clazz;
+            _key = key;
+            this.isRandom = isRandom;
+        }
+        
+        @Override @SuppressWarnings("unchecked")
+        public T call() throws Exception {
+            try {
+                PreparedStatement stmt = null;
+                StringBuilder sql = new StringBuilder("SELECT ");
+                sql.append(_tg.valueColumnName()).append(" FROM ").append(_tg.table());
+                sql.append(" WHERE ").append(_tg.pkColumnName()).append(" = ? FOR UPDATE");
+                
+                Transaction txn = Transaction.open("Sequence");
+                
+                PreparedStatement selectStmt = txn.prepareStatement(sql.toString());
+                if (_key == null) {
+                    selectStmt.setString(1, _tg.pkColumnValue());
+                } else {
+                    selectStmt.setObject(1, _key);
+                }
+
+                sql = new StringBuilder("UPDATE ");
+                sql.append(_tg.table()).append(" SET ").append(_tg.valueColumnName()).append("=").append("?+?");
+                sql.append(" WHERE ").append(_tg.pkColumnName()).append("=?");
+                
+                PreparedStatement updateStmt = txn.prepareStatement(sql.toString());
+                if(isRandom){
+                	updateStmt.setInt(2, random.nextInt(10) + 1);
+                } else {
+                	updateStmt.setInt(2, _tg.allocationSize());
+                }
+                if (_key == null) {
+                    updateStmt.setString(3, _tg.pkColumnValue());
+                } else {
+                    updateStmt.setObject(3, _key);
+                }
+                
+                ResultSet rs = null;
+                try {
+                    txn.start();
+                    
+                    stmt = selectStmt;
+                    rs = stmt.executeQuery();
+                    Object obj = null;
+                    while (rs.next()) {
+                        if (_clazz.isAssignableFrom(Long.class)) {
+                            obj = rs.getLong(1);
+                        } else if (_clazz.isAssignableFrom(Integer.class)) {
+                            obj = rs.getInt(1);
+                        } else {
+                            obj = rs.getObject(1);
+                        }
+                    }
+                    
+                    if (obj == null) {
+                        s_logger.warn("Unable to get a sequence: " + updateStmt.toString());
+                        return null;
+                    }
+                    
+                    updateStmt.setObject(1, obj);
+                    stmt = updateStmt;
+                    int rows = stmt.executeUpdate();
+                    assert rows == 1 : "Come on....how exactly did we update this many rows " + rows + " for " + updateStmt.toString();
+                    txn.commit();
+                    return (T)obj;
+                } catch (SQLException e) {
+                    s_logger.warn("Caught this exception when running: " + (stmt != null ? stmt.toString() : ""), e);
+                } finally {
+                    if (rs != null) {
+                        rs.close();
+                    }
+                    selectStmt.close();
+                    updateStmt.close();
+                    txn.close();
+                }
+            } catch (Exception e) {
+                s_logger.warn("Caught this exception when running.", e);
+            }
+            return null;
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/SqlGenerator.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SqlGenerator.java b/framework/db/src/com/cloud/utils/db/SqlGenerator.java
new file mode 100755
index 0000000..e48fee5
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/SqlGenerator.java
@@ -0,0 +1,669 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.CollectionTable;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.ElementCollection;
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.SecondaryTable;
+import javax.persistence.TableGenerator;
+
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.db.Attribute.Flag;
+
+public class SqlGenerator {
+    Class<?> _clazz;
+    ArrayList<Attribute> _attributes;
+    ArrayList<Field> _embeddeds;
+    ArrayList<Class<?>> _tables;
+    LinkedHashMap<String, List<Attribute>> _ids;
+    HashMap<String, TableGenerator> _generators;
+    ArrayList<Attribute> _ecAttrs;
+
+    public SqlGenerator(Class<?> clazz) {
+        _clazz = clazz;
+        _tables = new ArrayList<Class<?>>();
+        _attributes = new ArrayList<Attribute>();
+        _ecAttrs = new ArrayList<Attribute>();
+        _embeddeds = new ArrayList<Field>();
+        _ids = new LinkedHashMap<String, List<Attribute>>();
+        _generators = new HashMap<String, TableGenerator>();
+
+        buildAttributes(clazz, DbUtil.getTableName(clazz), DbUtil.getAttributeOverrides(clazz), false, false);
+        assert (_tables.size() > 0) : "Did you forget to put @Entity on " + clazz.getName();
+        handleDaoAttributes(clazz);
+        findEcAttributes();
+    }
+
+    protected boolean checkMethods(Class<?> clazz, Map<String, Attribute> attrs) {
+        Method[] methods = clazz.getMethods();
+        for (Method method : methods) {
+            String name = method.getName();
+            if (name.startsWith("get")) {
+                String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+                assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
+            } else if (name.startsWith("is")) {
+                String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
+                assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
+            } else if (name.startsWith("set")) {
+                String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+                assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
+            }
+        }
+        return true;
+
+    }
+
+    protected void buildAttributes(Class<?> clazz, String tableName, AttributeOverride[] overrides, boolean embedded, boolean isId) {
+        if (!embedded && clazz.getAnnotation(Entity.class) == null) {
+            return;
+        }
+
+        Class<?> parent = clazz.getSuperclass();
+        if (parent != null) {
+            buildAttributes(parent, DbUtil.getTableName(parent), DbUtil.getAttributeOverrides(parent), false, false);
+        }
+
+        if (!embedded) {
+            _tables.add(clazz);
+            _ids.put(tableName, new ArrayList<Attribute>());
+        }
+
+        Field[] fields = clazz.getDeclaredFields();
+        for (Field field : fields) {
+            field.setAccessible(true);
+
+            TableGenerator tg = field.getAnnotation(TableGenerator.class);
+            if (tg != null) {
+                _generators.put(field.getName(), tg);
+            }
+
+            if (!DbUtil.isPersistable(field)) {
+                continue;
+            }
+
+            if (field.getAnnotation(Embedded.class) != null) {
+                _embeddeds.add(field);
+                Class<?> embeddedClass = field.getType();
+                assert (embeddedClass.getAnnotation(Embeddable.class) != null) : "Class is not annotated with Embeddable: " + embeddedClass.getName();
+                buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, false);
+                continue;
+            }
+
+            if (field.getAnnotation(EmbeddedId.class) != null) {
+                _embeddeds.add(field);
+                Class<?> embeddedClass = field.getType();
+                assert (embeddedClass.getAnnotation(Embeddable.class) != null) : "Class is not annotated with Embeddable: " + embeddedClass.getName();
+                buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, true);
+                continue;
+            }
+
+            Attribute attr = new Attribute(clazz, overrides, field, tableName, embedded, isId);
+
+            if (attr.getColumnName().equals(GenericDao.REMOVED_COLUMN)) {
+                attr.setColumnName(GenericDao.REMOVED);
+                attr.setTrue(Attribute.Flag.DaoGenerated);
+                attr.setFalse(Attribute.Flag.Insertable);
+                attr.setFalse(Attribute.Flag.Updatable);
+                attr.setTrue(Attribute.Flag.TimeStamp);
+                attr.setFalse(Attribute.Flag.Time);
+                attr.setFalse(Attribute.Flag.Date);
+                attr.setTrue(Attribute.Flag.Nullable);
+                attr.setTrue(Attribute.Flag.Removed);
+            } 
+
+            if (attr.isId()) {
+                List<Attribute> attrs = _ids.get(tableName);
+                attrs.add(attr);
+            }
+
+            _attributes.add(attr);
+        }
+    }
+
+    protected void findEcAttributes() {
+        for (Attribute attr : _attributes) {
+            if (attr.field == null) {
+                continue;
+            }
+            ElementCollection ec = attr.field.getAnnotation(ElementCollection.class);
+            if (ec != null) {
+                Attribute idAttr = _ids.get(attr.table).get(0);
+                assert supportsElementCollection(attr.field) : "Doesn't support ElementCollection for " + attr.field.getName();
+                attr.attache = new EcInfo(attr, idAttr);
+                _ecAttrs.add(attr);
+            }
+        }
+    }
+
+    protected boolean supportsElementCollection(Field field) {
+        ElementCollection otm = field.getAnnotation(ElementCollection.class);
+        if (otm.fetch() == FetchType.LAZY) {
+            assert (false) : "Doesn't support laz fetch: " + field.getName();
+            return false;
+        }
+
+        CollectionTable ct = field.getAnnotation(CollectionTable.class);
+        if (ct == null) {
+            assert (false) : "No collection table sepcified for " + field.getName();
+            return false;
+        }
+
+        return true;
+    }
+
+    public Map<String, TableGenerator> getTableGenerators() {
+        return _generators;
+    }
+
+    protected void handleDaoAttributes(Class<?> clazz) {
+        Attribute attr;
+        Class<?> current = clazz;
+        while (current != null && current.getAnnotation(Entity.class) != null) {
+            DiscriminatorColumn column = current.getAnnotation(DiscriminatorColumn.class);
+            if (column != null) {
+                String columnName = column.name();
+                attr = findAttribute(columnName);
+                if (attr != null) {
+                    attr.setTrue(Attribute.Flag.DaoGenerated);
+                    attr.setTrue(Attribute.Flag.Insertable);
+                    attr.setTrue(Attribute.Flag.Updatable);
+                    attr.setFalse(Attribute.Flag.Nullable);
+                    attr.setTrue(Attribute.Flag.DC);
+                } else {
+                    attr = new Attribute(DbUtil.getTableName(current), column.name());
+                    attr.setFalse(Flag.Selectable);
+                    attr.setTrue(Flag.Insertable);
+                    attr.setTrue(Flag.DaoGenerated);
+                    attr.setTrue(Flag.DC);
+                    _attributes.add(attr);
+                }
+                if (column.discriminatorType() == DiscriminatorType.CHAR) {
+                    attr.setTrue(Attribute.Flag.CharDT);
+                } else if (column.discriminatorType() == DiscriminatorType.STRING) {
+                    attr.setTrue(Attribute.Flag.StringDT);
+                } else if (column.discriminatorType() == DiscriminatorType.INTEGER) {
+                    attr.setTrue(Attribute.Flag.IntegerDT);
+                }
+            }
+
+            PrimaryKeyJoinColumn[] pkjcs = DbUtil.getPrimaryKeyJoinColumns(current);
+            if (pkjcs != null) {
+                for (PrimaryKeyJoinColumn pkjc : pkjcs) {
+                    String tableName = DbUtil.getTableName(current);
+                    attr = findAttribute(pkjc.name());
+                    if (attr == null || !tableName.equals(attr.table)) {
+                        Attribute id = new Attribute(DbUtil.getTableName(current), pkjc.name());
+                        if (pkjc.referencedColumnName().length() > 0) {
+                            attr = findAttribute(pkjc.referencedColumnName());
+                            assert (attr != null) : "Couldn't find referenced column name " + pkjc.referencedColumnName();
+                        }
+                        id.field = attr.field;
+                        id.setTrue(Flag.Id);
+                        id.setTrue(Flag.Insertable);
+                        id.setFalse(Flag.Updatable);
+                        id.setFalse(Flag.Nullable);
+                        id.setFalse(Flag.Selectable);
+                        _attributes.add(id);
+                        List<Attribute> attrs = _ids.get(id.table);
+                        attrs.add(id);
+                    }
+                }
+            }
+            current = current.getSuperclass();
+        }
+
+        attr = findAttribute(GenericDao.CREATED_COLUMN);
+        if (attr != null && attr.field.getType() == Date.class) {
+            attr.setTrue(Attribute.Flag.DaoGenerated);
+            attr.setTrue(Attribute.Flag.Insertable);
+            attr.setFalse(Attribute.Flag.Updatable);
+            attr.setFalse(Attribute.Flag.Date);
+            attr.setFalse(Attribute.Flag.Time);
+            attr.setTrue(Attribute.Flag.TimeStamp);
+            attr.setFalse(Attribute.Flag.Nullable);
+            attr.setTrue(Attribute.Flag.Created);
+        }
+
+        attr = findAttribute(GenericDao.XID_COLUMN);
+        if (attr != null && attr.field.getType() == String.class) {
+            attr.setTrue(Attribute.Flag.DaoGenerated);
+            attr.setTrue(Attribute.Flag.Insertable);
+            attr.setFalse(Attribute.Flag.Updatable);
+            attr.setFalse(Attribute.Flag.TimeStamp);
+            attr.setFalse(Attribute.Flag.Time);
+            attr.setFalse(Attribute.Flag.Date);
+            attr.setFalse(Attribute.Flag.Nullable);
+            attr.setFalse(Attribute.Flag.Removed);
+        }
+    }
+
+    public List<Attribute> getElementCollectionAttributes() {
+        return _ecAttrs;
+    }
+
+    public Attribute findAttribute(String name) {
+        for (Attribute attr : _attributes) {
+
+            if (attr.columnName.equalsIgnoreCase(name)) {
+                if (attr.columnName.equalsIgnoreCase(GenericDao.REMOVED) && attr.isUpdatable()) {
+                    return null;
+                }
+                return attr;
+            }
+        }
+
+        return null;
+    }
+
+    public static StringBuilder buildUpdateSql(String tableName, List<Attribute> attrs) {
+        StringBuilder sql = new StringBuilder("UPDATE ");
+        sql.append(tableName).append(" SET ");
+        for (Attribute attr : attrs) {
+            sql.append(attr.columnName).append(" = ?, ");
+        }
+        sql.delete(sql.length() - 2, sql.length());
+        sql.append(" WHERE ");
+
+        return sql;
+    }
+
+    public List<Pair<StringBuilder, Attribute[]>> buildUpdateSqls() {
+        ArrayList<Pair<StringBuilder, Attribute[]>> sqls = new ArrayList<Pair<StringBuilder, Attribute[]>>(_tables.size());
+        for (Class<?> table : _tables) {
+            ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+            String tableName = DbUtil.getTableName(table);
+            for (Attribute attr : _attributes) {
+                if (attr.isUpdatable() && tableName.equals(attr.table)) {
+                    attrs.add(attr);
+                }
+            }
+            if (attrs.size() != 0) {
+                Pair<StringBuilder, Attribute[]> pair =
+                        new Pair<StringBuilder, Attribute[]>(buildUpdateSql(tableName, attrs), attrs.toArray(new Attribute[attrs.size()]));
+                        sqls.add(pair);
+            }
+        }
+        return sqls;
+    }
+
+    public static StringBuilder buildMysqlUpdateSql(String joins, Collection<Ternary<Attribute, Boolean, Object>> setters) {
+        if (setters.size() == 0) {
+            return null;
+        }
+
+        StringBuilder sql = new StringBuilder("UPDATE ");
+
+        sql.append(joins);
+
+        sql.append(" SET ");
+
+        for (Ternary<Attribute, Boolean, Object> setter : setters) {
+            Attribute attr = setter.first();
+            sql.append(attr.table).append(".").append(attr.columnName).append("=");
+            if (setter.second() != null) {
+                sql.append(attr.table).append(".").append(attr.columnName).append(setter.second() ? "+" : "-");
+            }
+            sql.append("?, ");
+        }
+
+        sql.delete(sql.length() - 2, sql.length());
+
+        sql.append(" WHERE ");
+
+        return sql;
+    }
+
+    public List<Pair<String, Attribute[]>> buildInsertSqls() {
+        LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>();
+        for (Class<?> table : _tables) {
+            map.put(DbUtil.getTableName(table), new ArrayList<Attribute>());
+        }
+
+        for (Attribute attr : _attributes) {
+            if (attr.isInsertable()) {
+                ArrayList<Attribute> attrs = map.get(attr.table);
+                assert (attrs != null) : "Null set of attributes for " + attr.table;
+                attrs.add(attr);
+            }
+        }
+
+        List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size());
+        for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) {
+            ArrayList<Attribute> attrs = entry.getValue();
+            StringBuilder sql = buildInsertSql(entry.getKey(), attrs);
+            Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql.toString(), attrs.toArray(new Attribute[attrs.size()]));
+            sqls.add(pair);
+        }
+
+        return sqls;
+    }
+
+    protected StringBuilder buildInsertSql(String table, ArrayList<Attribute> attrs) {
+        StringBuilder sql = new StringBuilder("INSERT INTO ");
+        sql.append(table).append(" (");
+        for (Attribute attr : attrs) {
+            sql.append(table).append(".").append(attr.columnName).append(", ");
+        }
+        if (attrs.size() > 0) {
+            sql.delete(sql.length() - 2, sql.length());
+        }
+
+        sql.append(") VALUES (");
+        for (Attribute attr : attrs) {
+            sql.append("?, ");
+        }
+
+        if (attrs.size() > 0) {
+            sql.delete(sql.length() - 2, sql.length());
+        }
+
+        sql.append(")");
+
+        return sql;
+    }
+
+    protected List<Pair<String, Attribute[]>> buildDeleteSqls() {
+        LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>();
+        for (Class<?> table : _tables) {
+            map.put(DbUtil.getTableName(table), new ArrayList<Attribute>());
+        }
+
+        for (Attribute attr : _attributes) {
+            if (attr.isId()) {
+                ArrayList<Attribute> attrs = map.get(attr.table);
+                assert (attrs != null) : "Null set of attributes for " + attr.table;
+                attrs.add(attr);
+            }
+        }
+
+        List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size());
+        for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) {
+            ArrayList<Attribute> attrs = entry.getValue();
+            String sql = buildDeleteSql(entry.getKey(), attrs);
+            Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()]));
+            sqls.add(pair);
+        }
+
+        Collections.reverse(sqls);
+        return sqls;
+    }
+
+    protected String buildDeleteSql(String table, ArrayList<Attribute> attrs) {
+        StringBuilder sql = new StringBuilder("DELETE FROM ");
+        sql.append(table).append(" WHERE ");
+        for (Attribute attr : attrs) {
+            sql.append(table).append(".").append(attr.columnName).append("= ? AND ");
+        }
+        sql.delete(sql.length() - 5, sql.length());
+        return sql.toString();
+    }
+
+    public Pair<String, Attribute[]> buildRemoveSql() {
+        Attribute attribute = findAttribute(GenericDao.REMOVED);
+        if (attribute == null) {
+            return null;
+        }
+
+        StringBuilder sql = new StringBuilder("UPDATE ");
+        sql.append(attribute.table).append(" SET ");
+        sql.append(attribute.columnName).append(" = ? WHERE ");
+
+        List<Attribute> ids = _ids.get(attribute.table);
+
+        // if ids == null, that means the removed column was added as a JOIN
+        // value to another table.  We ignore it here.
+        if (ids == null) {
+            return null;
+        }
+        if (ids.size() == 0) {
+            return null;
+        }
+
+        for (Attribute id : ids) {
+            sql.append(id.table).append(".").append(id.columnName).append(" = ? AND ");
+        }
+
+        sql.delete(sql.length() - 5, sql.length());
+
+        Attribute[] attrs = ids.toArray(new Attribute[ids.size() + 1]);
+        attrs[attrs.length - 1] = attribute;
+
+        return new Pair<String, Attribute[]>(sql.toString(), attrs);
+    }
+
+    public Map<String, Attribute[]> getIdAttributes() {
+        LinkedHashMap<String, Attribute[]> ids = new LinkedHashMap<String, Attribute[]>(_ids.size());
+
+        for (Map.Entry<String, List<Attribute>> entry : _ids.entrySet()) {
+            ids.put(entry.getKey(), entry.getValue().toArray(new Attribute[entry.getValue().size()]));
+        }
+
+        return ids;
+    }
+
+    /**
+     * @return a map of tables and maps of field names to attributes.
+     */
+    public Map<String, Attribute> getAllAttributes() {
+        Map<String, Attribute> attrs = new LinkedHashMap<String, Attribute>(_attributes.size());
+        for (Attribute attr : _attributes) {
+            if (attr.field != null) {
+                attrs.put(attr.field.getName(), attr);
+            }
+        }
+
+        return attrs;
+    }
+
+    public Map<Pair<String, String>, Attribute> getAllColumns() {
+        Map<Pair<String, String>, Attribute> attrs = new LinkedHashMap<Pair<String, String>, Attribute>(_attributes.size());
+        for (Attribute attr : _attributes) {
+            if (attr.columnName != null) {
+                attrs.put(new Pair<String, String>(attr.table, attr.columnName), attr);
+            }
+        }
+
+        return attrs;
+    }
+
+    protected static void addPrimaryKeyJoinColumns(StringBuilder sql, String fromTable, String toTable, String joinType, PrimaryKeyJoinColumn[] pkjcs) {
+        if ("right".equalsIgnoreCase(joinType)) {
+            sql.append(" RIGHT JOIN ").append(toTable).append(" ON ");
+        } else if ("left".equalsIgnoreCase(joinType)) {
+            sql.append(" LEFT JOIN ").append(toTable).append(" ON ");
+        } else {
+            sql.append(" INNER JOIN ").append(toTable).append(" ON ");
+        }
+        for (PrimaryKeyJoinColumn pkjc : pkjcs) {
+            sql.append(fromTable).append(".").append(pkjc.name());
+            String refColumn = DbUtil.getReferenceColumn(pkjc);
+            sql.append("=").append(toTable).append(".").append(refColumn).append(" ");
+        }
+    }
+
+    public Pair<String, Attribute> getRemovedAttribute() {
+        Attribute removed = findAttribute(GenericDao.REMOVED);
+        if (removed == null) {
+            return null;
+        }
+
+        if (removed.field.getType() != Date.class) {
+            return null;
+        }
+
+        StringBuilder sql = new StringBuilder();
+        sql.append(removed.table).append(".").append(removed.columnName).append(" IS NULL ");
+
+        return new Pair<String, Attribute>(sql.toString(), removed);
+    }
+
+    protected static void buildJoins(StringBuilder innerJoin, Class<?> clazz) {
+        String tableName = DbUtil.getTableName(clazz);
+
+        SecondaryTable[] sts = DbUtil.getSecondaryTables(clazz);
+        ArrayList<String> secondaryTables = new ArrayList<String>();
+        for (SecondaryTable st : sts) {
+            JoinType jt = clazz.getAnnotation(JoinType.class);
+            String join = null;
+            if (jt != null) {
+                join = jt.type();
+            }
+            addPrimaryKeyJoinColumns(innerJoin, tableName, st.name(), join, st.pkJoinColumns());
+            secondaryTables.add(st.name());
+        }
+
+        Class<?> parent = clazz.getSuperclass();
+        if (parent.getAnnotation(Entity.class) != null) {
+            String table = DbUtil.getTableName(parent);
+            PrimaryKeyJoinColumn[] pkjcs = DbUtil.getPrimaryKeyJoinColumns(clazz);
+            assert (pkjcs != null) : "No Join columns specified for the super class";
+            addPrimaryKeyJoinColumns(innerJoin, tableName, table, null, pkjcs);
+        }
+    }
+
+
+    public String buildTableReferences() {
+        StringBuilder sql = new StringBuilder();
+        sql.append(DbUtil.getTableName(_tables.get(_tables.size() - 1)));
+
+        for (Class<?> table : _tables) {
+            buildJoins(sql, table);
+        }
+
+        return sql.toString();
+    }
+
+    public Pair<StringBuilder, Attribute[]> buildSelectSql(boolean enable_query_cache) {
+        StringBuilder sql = new StringBuilder("SELECT ");
+
+        sql.append(enable_query_cache ? "SQL_CACHE ": "");
+
+        ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+
+        for (Attribute attr : _attributes) {
+            if (attr.isSelectable()) {
+                attrs.add(attr);
+                sql.append(attr.table).append(".").append(attr.columnName).append(", ");
+            }
+        }
+
+        if (attrs.size() > 0) {
+            sql.delete(sql.length() - 2, sql.length());
+        }
+
+        sql.append(" FROM ").append(buildTableReferences());
+
+        sql.append(" WHERE ");
+
+        sql.append(buildDiscriminatorClause().first());
+
+        return new Pair<StringBuilder, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()]));
+    }
+
+    public Pair<StringBuilder, Attribute[]> buildSelectSql(Attribute[] attrs) {
+        StringBuilder sql = new StringBuilder("SELECT ");
+
+        for (Attribute attr : attrs) {
+            sql.append(attr.table).append(".").append(attr.columnName).append(", ");
+        }
+
+        if (attrs.length > 0) {
+            sql.delete(sql.length() - 2, sql.length());
+        }
+
+        sql.append(" FROM ").append(buildTableReferences());
+
+        sql.append(" WHERE ");
+
+        sql.append(buildDiscriminatorClause().first());
+
+        return new Pair<StringBuilder, Attribute[]>(sql, attrs);
+    }
+
+    /**
+     * buildDiscriminatorClause builds the join clause when there are multiple tables.
+     * 
+     * @return
+     */
+    public Pair<StringBuilder, Map<String, Object>> buildDiscriminatorClause() {
+        StringBuilder sql = new StringBuilder();
+        Map<String, Object> values = new HashMap<String, Object>();
+
+        for (Class<?> table : _tables) {
+            DiscriminatorValue dv = table.getAnnotation(DiscriminatorValue.class);
+            if (dv != null) {
+                Class<?> parent = table.getSuperclass();
+                String tableName = DbUtil.getTableName(parent);
+                DiscriminatorColumn dc = parent.getAnnotation(DiscriminatorColumn.class);
+                assert(dc != null) : "Parent does not have discrminator column: " + parent.getName();
+                sql.append(tableName);
+                sql.append(".");
+                sql.append(dc.name()).append("=");
+                Object value = null;
+                if (dc.discriminatorType() == DiscriminatorType.INTEGER) {
+                    sql.append(dv.value());
+                    value = Integer.parseInt(dv.value());
+                } else if (dc.discriminatorType() == DiscriminatorType.CHAR) {
+                    sql.append(dv.value());
+                    value = dv.value().charAt(0);
+                } else if (dc.discriminatorType() == DiscriminatorType.STRING) {
+                    String v = dv.value();
+                    v = v.substring(0, v.length() < dc.length() ? v.length() : dc.length());
+                    sql.append("'").append(v).append("'");
+                    value = v;
+                }
+                values.put(dc.name(), value);
+                sql.append(" AND ");
+            }
+        }
+
+        return new Pair<StringBuilder, Map<String, Object>>(sql, values);
+    }
+
+    public Field[] getEmbeddedFields() {
+        return _embeddeds.toArray(new Field[_embeddeds.size()]);
+    }
+
+    public String buildCountSql() {
+        StringBuilder sql = new StringBuilder();
+
+        return sql.append("SELECT COUNT(*) FROM ").append(buildTableReferences()).
+                append(" WHERE ").append(buildDiscriminatorClause().first()).toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/StateMachine.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/StateMachine.java b/framework/db/src/com/cloud/utils/db/StateMachine.java
new file mode 100644
index 0000000..a667d9b
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/StateMachine.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Target(FIELD)
+@Retention(RUNTIME)
+public @interface StateMachine {
+    public Class<?> state();
+    public Class<?> event();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/Transaction.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/Transaction.java b/framework/db/src/com/cloud/utils/db/Transaction.java
new file mode 100755
index 0000000..37ea8cf
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/Transaction.java
@@ -0,0 +1,1174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.ConnectionFactory;
+import org.apache.commons.dbcp.DriverManagerConnectionFactory;
+import org.apache.commons.dbcp.PoolableConnectionFactory;
+import org.apache.commons.dbcp.PoolingDataSource;
+import org.apache.commons.pool.KeyedObjectPoolFactory;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory;
+import org.apache.log4j.Logger;
+import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
+import org.jasypt.properties.EncryptableProperties;
+
+import com.cloud.utils.Pair;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.mgmt.JmxUtil;
+
+/**
+ * Transaction abstracts away the Connection object in JDBC.  It allows the
+ * following things that the Connection object does not.
+ * 
+ *   1. Transaction can be started at an entry point and whether the DB
+ *      actions should be auto-commit or not determined at that point.
+ *   2. DB Connection is allocated only when it is needed.
+ *   3. Code does not need to know if a transaction has been started or not.
+ *      It just starts/ends a transaction and we resolve it correctly with
+ *      the previous actions.
+ *
+ * Note that this class is not synchronous but it doesn't need to be because
+ * it is stored with TLS and is one per thread.  Use appropriately.
+ */
+public class Transaction {
+    private static final Logger s_logger = Logger.getLogger(Transaction.class.getName() + "." + "Transaction");
+    private static final Logger s_stmtLogger = Logger.getLogger(Transaction.class.getName() + "." + "Statement");
+    private static final Logger s_lockLogger = Logger.getLogger(Transaction.class.getName() + "." + "Lock");
+    private static final Logger s_connLogger = Logger.getLogger(Transaction.class.getName() + "." + "Connection");
+
+    private static final ThreadLocal<Transaction> tls = new ThreadLocal<Transaction>();
+    private static final String START_TXN = "start_txn";
+    private static final String CURRENT_TXN = "current_txn";
+    private static final String CREATE_TXN = "create_txn";
+    private static final String CREATE_CONN = "create_conn";
+    private static final String STATEMENT = "statement";
+    private static final String ATTACHMENT = "attachment";
+
+    public static final short CLOUD_DB = 0;
+    public static final short USAGE_DB = 1;
+    public static final short AWSAPI_DB = 2;
+    public static final short SIMULATOR_DB = 3;
+    public static final short CONNECTED_DB = -1;
+    public static int s_region_id;
+
+    private static AtomicLong s_id = new AtomicLong();
+    private static final TransactionMBeanImpl s_mbean = new TransactionMBeanImpl();
+    static {
+        try {
+            JmxUtil.registerMBean("Transaction", "Transaction", s_mbean);
+        } catch (Exception e) {
+            s_logger.error("Unable to register mbean for transaction", e);
+        }
+        
+        /* FIXME: We need a better solution for this
+         * Initialize encryption if we need it for db.properties
+         */ 
+        EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker();
+        enc.check();  
+    }
+
+    private final LinkedList<StackElement> _stack;
+    private long _id;
+
+    private final LinkedList<Pair<String, Long>> _lockTimes = new LinkedList<Pair<String, Long>>();
+
+    private String _name;
+    private Connection _conn;
+    private boolean _txn;
+    private short _dbId;
+    private long _txnTime;
+    private Statement _stmt;
+    private String _creator;
+
+    private Transaction _prev = null;
+
+    public static Transaction currentTxn() {
+        Transaction txn = tls.get();
+        assert txn != null : "No Transaction on stack.  Did you mark the method with @DB?";
+
+        assert checkAnnotation(3, txn) : "Did you even read the guide to use Transaction...IOW...other people's code? Try method can't be private.  What about @DB? hmmm... could that be it? " + txn;
+        return txn;
+    }
+
+    public static Transaction open(final short databaseId) {
+        String name = buildName();
+        if (name == null) {
+            name = CURRENT_TXN;
+        }
+        return open(name, databaseId, true);
+    }
+
+    //
+    // Usage of this transaction setup should be limited, it will always open a new transaction context regardless of whether or not there is other
+    // transaction context in the stack. It is used in special use cases that we want to control DB connection explicitly and in the mean time utilize
+    // the existing DAO features
+    //
+    public void transitToUserManagedConnection(Connection conn) {
+        assert(_conn == null /*&& _stack.size() <= 1*/) : "Can't change to a user managed connection unless the stack is empty and the db connection is null, you may have forgotten to invoke transitToAutoManagedConnection to close out the DB connection: " + toString();
+        _conn = conn;
+        _dbId = CONNECTED_DB;
+    }
+
+    public void transitToAutoManagedConnection(short dbId) {
+        // assert(_stack.size() <= 1) : "Can't change to auto managed connection unless your stack is empty";
+        _dbId = dbId;
+        _conn = null;
+    }
+
+    public static Transaction open(final String name) {
+        return open(name, CLOUD_DB, false);
+    }
+
+    public static Transaction open(final String name, final short databaseId, final boolean forceDbChange) {
+        Transaction txn = tls.get();
+        boolean isNew = false;
+        if (txn == null) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Creating the transaction: " + name);
+            }
+            txn = new Transaction(name, false, databaseId);
+            tls.set(txn);
+            isNew = true;
+        } else if (forceDbChange) {
+            final short currentDbId = txn.getDatabaseId();
+            if (currentDbId != databaseId) {
+                // we need to end the current transaction and switch databases
+                txn.close(txn.getName());
+
+                txn = new Transaction(name, false, databaseId);
+                tls.set(txn);
+                isNew = true;
+            }
+        }
+
+        txn.takeOver(name, false);
+        if (isNew) {
+            s_mbean.addTransaction(txn);
+        }
+        return txn;
+    }
+
+    protected StackElement peekInStack(Object obj) {
+        final Iterator<StackElement> it = _stack.iterator();
+        while (it.hasNext()) {
+            StackElement next = it.next();
+            if (next.type == obj) {
+                return next;
+            }
+        }
+        return null;
+    }
+
+    public void registerLock(String sql) {
+        if (_txn && s_lockLogger.isDebugEnabled()) {
+            Pair<String, Long> time = new Pair<String, Long>(sql, System.currentTimeMillis());
+            _lockTimes.add(time);
+        }
+    }
+
+    public boolean dbTxnStarted() {
+        return _txn;
+    }
+
+    public static Connection getStandaloneConnectionWithException() throws SQLException {
+        Connection conn = s_ds.getConnection();
+        if (s_connLogger.isTraceEnabled()) {
+            s_connLogger.trace("Retrieving a standalone connection: dbconn" + System.identityHashCode(conn));
+        }
+        return conn;
+    }
+
+    public static Connection getStandaloneConnection() {
+        try {
+            return getStandaloneConnectionWithException();
+        } catch (SQLException e) {
+            s_logger.error("Unexpected exception: ", e);
+            return null;
+        }
+    }
+
+    public static Connection getStandaloneUsageConnection() {
+        try {
+            Connection conn = s_usageDS.getConnection();
+            if (s_connLogger.isTraceEnabled()) {
+                s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn));
+            }
+            return conn;
+        } catch (SQLException e) {
+            s_logger.warn("Unexpected exception: ", e);
+            return null;
+        }
+    }
+
+    public static Connection getStandaloneAwsapiConnection() {
+        try {
+            Connection conn = s_awsapiDS.getConnection();
+            if (s_connLogger.isTraceEnabled()) {
+                s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn));
+            }
+            return conn;
+        } catch (SQLException e) {
+            s_logger.warn("Unexpected exception: ", e);
+            return null;
+        }
+    }
+    
+    public static Connection getStandaloneSimulatorConnection() {
+    	try {
+    		Connection conn = s_simulatorDS.getConnection();
+    		if (s_connLogger.isTraceEnabled()) {
+                s_connLogger.trace("Retrieving a standalone connection for simulator: dbconn" + System.identityHashCode(conn));
+            }
+            return conn;
+        } catch (SQLException e) {
+            s_logger.warn("Unexpected exception: ", e);
+            return null;
+        }
+    }
+
+    protected void attach(TransactionAttachment value) {
+        _stack.push(new StackElement(ATTACHMENT, value));
+    }
+
+    protected TransactionAttachment detach(String name) {
+        Iterator<StackElement> it = _stack.descendingIterator();
+        while (it.hasNext()) {
+            StackElement element = it.next();
+            if (element.type == ATTACHMENT) {
+                TransactionAttachment att = (TransactionAttachment)element.ref;
+                if (name.equals(att.getName())) {
+                    it.remove();
+                    return att;
+                }
+            }
+        }
+        assert false : "Are you sure you attached this: " + name;
+        return null;
+    }
+
+    public static void attachToTxn(TransactionAttachment value) {
+        Transaction txn = tls.get();
+        assert txn != null && txn.peekInStack(CURRENT_TXN) != null: "Come on....how can we attach something to the transaction if you haven't started it?";
+
+        txn.attach(value);
+    }
+
+    public static TransactionAttachment detachFromTxn(String name) {
+        Transaction txn = tls.get();
+        assert txn != null : "No Transaction in TLS";
+        return txn.detach(name);
+    }
+
+    protected static boolean checkAnnotation(int stack, Transaction txn) {
+        final StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
+        StackElement se = txn.peekInStack(CURRENT_TXN);
+        if (se == null) {
+            return false;
+        }
+        for (; stack < stacks.length; stack++) {
+            String methodName = stacks[stack].getMethodName();
+            if (methodName.equals(se.ref)){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected static String buildName() {
+        if (s_logger.isDebugEnabled()) {
+            final StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
+            final StringBuilder str = new StringBuilder();
+            int i = 3, j = 3;
+            while (j < 15 && i < stacks.length) {
+                StackTraceElement element = stacks[i];
+                String filename = element.getFileName();
+                String method = element.getMethodName();
+                if ((filename != null && filename.equals("<generated>")) || (method != null && method.equals("invokeSuper"))) {
+                    i++;
+                    continue;
+                }
+
+                str.append("-").append(stacks[i].getClassName().substring(stacks[i].getClassName().lastIndexOf(".") + 1)).append(".").append(stacks[i].getMethodName()).append(":").append(stacks[i].getLineNumber());
+                j++;
+                i++;
+            }
+            return str.toString();
+        }
+
+        return "";
+    }
+
+    public Transaction(final String name, final boolean forLocking, final short databaseId) {
+        _name = name;
+        _conn = null;
+        _stack = new LinkedList<StackElement>();
+        _txn = false;
+        _dbId = databaseId;
+        _id = s_id.incrementAndGet();
+        _creator = Thread.currentThread().getName();
+    }
+
+    public String getCreator() {
+        return _creator;
+    }
+
+    public long getId() {
+        return _id;
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public Short getDatabaseId() {
+        return _dbId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder str = new StringBuilder((_name != null ? _name : ""));
+        str.append(" : ");
+        for (final StackElement se : _stack) {
+            if (se.type == CURRENT_TXN) {
+                str.append(se.ref).append(", ");
+            }
+        }
+
+        return str.toString();
+    }
+
+    protected void mark(final String name) {
+        _stack.push(new StackElement(CURRENT_TXN, name));
+    }
+
+    public boolean lock(final String name, final int timeoutSeconds) {
+        Merovingian2 lockMaster = Merovingian2.getLockMaster();
+        if (lockMaster == null) {
+            throw new CloudRuntimeException("There's no support for locking yet");
+        }
+        return lockMaster.acquire(name, timeoutSeconds);
+    }
+
+    public boolean release(final String name) {
+        Merovingian2 lockMaster = Merovingian2.getLockMaster();
+        if (lockMaster == null) {
+            throw new CloudRuntimeException("There's no support for locking yet");
+        }
+        return lockMaster.release(name);
+    }
+
+    public void start() {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("txn: start requested by: " + buildName());
+        }
+
+        _stack.push(new StackElement(START_TXN, null));
+
+        if (_txn) {
+            s_logger.trace("txn: has already been started.");
+            return;
+        }
+
+        _txn = true;
+
+        _txnTime = System.currentTimeMillis();
+        if (_conn != null) {
+            try {
+                s_logger.trace("txn: set auto commit to false");
+                _conn.setAutoCommit(false);
+            } catch (final SQLException e) {
+                s_logger.warn("Unable to set auto commit: ", e);
+                throw new CloudRuntimeException("Unable to set auto commit: ", e);
+            }
+        }
+    }
+
+    protected void closePreviousStatement() {
+        if (_stmt != null) {
+            try {
+                if (s_stmtLogger.isTraceEnabled()) {
+                    s_stmtLogger.trace("Closing: " + _stmt.toString());
+                }
+                try {
+                    ResultSet rs = _stmt.getResultSet();
+                    if (rs != null && _stmt.getResultSetHoldability() != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
+                        rs.close();
+                    }
+                } catch(SQLException e) {
+                    s_stmtLogger.trace("Unable to close resultset");
+                }
+                _stmt.close();
+            } catch (final SQLException e) {
+                s_stmtLogger.trace("Unable to close statement: " + _stmt.toString());
+            } finally {
+                _stmt = null;
+            }
+        }
+    }
+
+    /**
+     * Prepares an auto close statement.  The statement is closed automatically if it is
+     * retrieved with this method.
+     * 
+     * @param sql sql String
+     * @return PreparedStatement
+     * @throws SQLException if problem with JDBC layer.
+     * 
+     * @see java.sql.Connection
+     */
+    public PreparedStatement prepareAutoCloseStatement(final String sql) throws SQLException {
+        PreparedStatement stmt = prepareStatement(sql);
+        closePreviousStatement();
+        _stmt = stmt;
+        return stmt;
+    }
+
+    public PreparedStatement prepareStatement(final String sql) throws SQLException {
+        final Connection conn = getConnection();
+        final PreparedStatement pstmt = conn.prepareStatement(sql);
+        if (s_stmtLogger.isTraceEnabled()) {
+            s_stmtLogger.trace("Preparing: " + sql);
+        }
+        return pstmt;
+    }
+
+    /**
+     * Prepares an auto close statement.  The statement is closed automatically if it is
+     * retrieved with this method.
+     * 
+     * @param sql sql String
+     * @param autoGeneratedKeys keys that are generated
+     * @return PreparedStatement
+     * @throws SQLException if problem with JDBC layer.
+     * 
+     * @see java.sql.Connection
+     */
+    public PreparedStatement prepareAutoCloseStatement(final String sql, final int autoGeneratedKeys) throws SQLException {
+        final Connection conn = getConnection();
+        final PreparedStatement pstmt = conn.prepareStatement(sql, autoGeneratedKeys);
+        if (s_stmtLogger.isTraceEnabled()) {
+            s_stmtLogger.trace("Preparing: " + sql);
+        }
+        closePreviousStatement();
+        _stmt = pstmt;
+        return pstmt;
+    }
+
+    /**
+     * Prepares an auto close statement.  The statement is closed automatically if it is
+     * retrieved with this method.
+     * 
+     * @param sql sql String
+     * @param columnNames names of the columns
+     * @return PreparedStatement
+     * @throws SQLException if problem with JDBC layer.
+     * 
+     * @see java.sql.Connection
+     */
+    public PreparedStatement prepareAutoCloseStatement(final String sql, final String[] columnNames) throws SQLException {
+        final Connection conn = getConnection();
+        final PreparedStatement pstmt = conn.prepareStatement(sql, columnNames);
+        if (s_stmtLogger.isTraceEnabled()) {
+            s_stmtLogger.trace("Preparing: " + sql);
+        }
+        closePreviousStatement();
+        _stmt = pstmt;
+        return pstmt;
+    }
+
+    /**
+     * Prepares an auto close statement.  The statement is closed automatically if it is
+     * retrieved with this method.
+     * 
+     * @param sql sql String
+     * @return PreparedStatement
+     * @throws SQLException if problem with JDBC layer.
+     * 
+     * @see java.sql.Connection
+     */
+    public PreparedStatement prepareAutoCloseStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        final Connection conn = getConnection();
+        final PreparedStatement pstmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+        if (s_stmtLogger.isTraceEnabled()) {
+            s_stmtLogger.trace("Preparing: " + sql);
+        }
+        closePreviousStatement();
+        _stmt = pstmt;
+        return pstmt;
+    }
+
+    /**
+     * Returns the db connection.
+     * 
+     * Note: that you can call getConnection() but beaware that
+     * all prepare statements from the Connection are not garbage
+     * collected!
+     * 
+     * @return DB Connection but make sure you understand that
+     *         you are responsible for closing the PreparedStatement.
+     * @throws SQLException
+     */
+    public Connection getConnection() throws SQLException {
+        if (_conn == null) {
+            switch (_dbId) {
+            case CLOUD_DB:
+                if(s_ds != null) {
+                    _conn = s_ds.getConnection();
+                } else {
+                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
+                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
+                }
+                break;
+            case USAGE_DB:
+                if(s_usageDS != null) {
+                    _conn = s_usageDS.getConnection();
+                } else {
+                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
+                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
+                }
+                break;
+            case AWSAPI_DB:
+        	if(s_awsapiDS != null) {
+        	    _conn = s_awsapiDS.getConnection();
+        	} else {
+        	    s_logger.warn("A static-initialized variable becomes null, process is dying?");
+                throw new CloudRuntimeException("Database is not initialized, process is dying?");
+        	}
+                break;
+
+            case SIMULATOR_DB:
+                if(s_simulatorDS != null) {
+                    _conn = s_simulatorDS.getConnection();
+                } else {
+                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
+                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
+                }
+                break;
+            default:
+
+        	throw new CloudRuntimeException("No database selected for the transaction");
+            }
+            _conn.setAutoCommit(!_txn);
+
+            //
+            // MySQL default transaction isolation level is REPEATABLE READ,
+            // to reduce chances of DB deadlock, we will use READ COMMITED isolation level instead
+            // see http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html
+            //
+            _stack.push(new StackElement(CREATE_CONN, null));
+            if (s_connLogger.isTraceEnabled()) {
+                s_connLogger.trace("Creating a DB connection with " + (_txn ? " txn: " : " no txn: ") + " for " + _dbId + ": dbconn" + System.identityHashCode(_conn) + ". Stack: " + buildName());
+            }
+        } else {
+            s_logger.trace("conn: Using existing DB connection");
+        }
+
+        return _conn;
+    }
+
+    protected boolean takeOver(final String name, final boolean create) {
+        if (_stack.size() != 0) {
+            if (!create) {
+                // If it is not a create transaction, then let's just use the current one.
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Using current transaction: " + toString());
+                }
+                mark(name);
+                return false;
+            }
+
+            final StackElement se = _stack.getFirst();
+            if (se.type == CREATE_TXN) {
+                // This create is called inside of another create.  Which is ok?
+                // We will let that create be responsible for cleaning up.
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Create using current transaction: " + toString());
+                }
+                mark(name);
+                return false;
+            }
+
+            s_logger.warn("Encountered a transaction that has leaked.  Cleaning up. " + toString());
+            cleanup();
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Took over the transaction: " + name);
+        }
+        _stack.push(new StackElement(create ? CREATE_TXN : CURRENT_TXN, name));
+        _name = name;
+        return true;
+    }
+
+    public void cleanup() {
+        closePreviousStatement();
+
+        removeUpTo(null, null);
+        if (_txn) {
+            rollbackTransaction();
+        }
+        _txn = false;
+        _name = null;
+
+        closeConnection();
+
+        _stack.clear();
+        Merovingian2 lockMaster = Merovingian2.getLockMaster();
+        if (lockMaster != null) {
+            lockMaster.cleanupThread();
+        }
+    }
+
+    public void close() {
+        removeUpTo(CURRENT_TXN, null);
+
+        if (_stack.size() == 0) {
+            s_logger.trace("Transaction is done");
+            cleanup();
+        }
+    }
+
+    /**
+     * close() is used by endTxn to close the connection.  This method only
+     * closes the connection if the name is the same as what's stored.
+     * 
+     * @param name
+     * @return true if this close actually closes the connection.  false if not.
+     */
+    public boolean close(final String name) {
+        if (_name == null) {    // Already cleaned up.
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Already cleaned up." + buildName());
+            }
+            return true;
+        }
+
+        if (!_name.equals(name)) {
+            close();
+            return false;
+        }
+
+        if (s_logger.isDebugEnabled() && _stack.size() > 2) {
+            s_logger.debug("Transaction is not closed properly: " + toString() + ".  Called by " + buildName());
+        }
+
+        cleanup();
+
+        s_logger.trace("All done");
+        return true;
+    }
+
+    protected boolean hasTxnInStack() {
+        return peekInStack(START_TXN) != null;
+    }
+
+    protected void clearLockTimes() {
+        if (s_lockLogger.isDebugEnabled()) {
+            for (Pair<String, Long> time : _lockTimes) {
+                s_lockLogger.trace("SQL " + time.first() + " took " + (System.currentTimeMillis() - time.second()));
+            }
+            _lockTimes.clear();
+        }
+    }
+
+    public boolean commit() {
+        if (!_txn) {
+            s_logger.warn("txn: Commit called when it is not a transaction: " + buildName());
+            return false;
+        }
+
+        Iterator<StackElement> it = _stack.iterator();
+        while (it.hasNext()) {
+            StackElement st = it.next();
+            if (st.type == START_TXN) {
+                it.remove();
+                break;
+            }
+        }
+
+        if (hasTxnInStack()) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("txn: Not committing because transaction started elsewhere: " + buildName() + " / " + toString());
+            }
+            return false;
+        }
+
+        _txn = false;
+        try {
+            if (_conn != null) {
+                _conn.commit();
+                s_logger.trace("txn: DB Changes committed. Time = " + (System.currentTimeMillis() - _txnTime));
+                clearLockTimes();
+                closeConnection();
+            }
+            return true;
+        } catch (final SQLException e) {
+            rollbackTransaction();
+            throw new CloudRuntimeException("Unable to commit or close the connection. ", e);
+        }
+    }
+
+    protected void closeConnection() {
+        closePreviousStatement();
+
+        if (_conn == null) {
+            return;
+        }
+
+        if (_txn) {
+            s_connLogger.trace("txn: Not closing DB connection because we're still in a transaction.");
+            return;
+        }
+
+        try {
+            // we should only close db connection when it is not user managed
+            if (this._dbId != CONNECTED_DB) {
+                if (s_connLogger.isTraceEnabled()) {
+                    s_connLogger.trace("Closing DB connection: dbconn" + System.identityHashCode(_conn));
+                }                                
+                _conn.close();
+                _conn = null;  
+            }
+
+        } catch (final SQLException e) {
+            s_logger.warn("Unable to close connection", e);
+        }
+    }
+
+    protected void removeUpTo(String type, Object ref) {
+        boolean rollback = false;
+        Iterator<StackElement> it = _stack.iterator();
+        while (it.hasNext()) {
+            StackElement item = it.next();
+
+            it.remove();
+
+            try {
+                if (item.type == type && (ref == null || item.ref == ref)) {
+                    break;
+                }
+
+                if (item.type == CURRENT_TXN) {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Releasing the current txn: " + (item.ref != null ? item.ref : ""));
+                    }
+                } else if (item.type == CREATE_CONN) {
+                    closeConnection();
+                } else if (item.type == START_TXN) {
+                    if (item.ref == null) {
+                        rollback = true;
+                    } else {
+                        try {
+                            _conn.rollback((Savepoint)ref);
+                            rollback = false;
+                        } catch (final SQLException e) {
+                            s_logger.warn("Unable to rollback Txn.", e);
+                        }
+                    }
+                } else if (item.type == STATEMENT) {
+                    try {
+                        if (s_stmtLogger.isTraceEnabled()) {
+                            s_stmtLogger.trace("Closing: " + ref.toString());
+                        }
+                        Statement stmt = (Statement)ref;
+                        try {
+                            ResultSet rs = stmt.getResultSet();
+                            if (rs != null) {
+                                rs.close();
+                            }
+                        } catch(SQLException e) {
+                            s_stmtLogger.trace("Unable to close resultset");
+                        }
+                        stmt.close();
+                    } catch (final SQLException e) {
+                        s_stmtLogger.trace("Unable to close statement: " + item);
+                    }
+                } else if (item.type == ATTACHMENT) {
+                    TransactionAttachment att = (TransactionAttachment)item.ref;
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Cleaning up " + att.getName());
+                    }
+                    att.cleanup();
+                }
+            } catch(Exception e) {
+                s_logger.error("Unable to clean up " + item, e);
+            }
+        }
+
+        if (rollback) {
+            rollback();
+        }
+    }
+
+    protected void rollbackTransaction() {
+        closePreviousStatement();
+        if (!_txn) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Rollback called for " + _name + " when there's no transaction: " + buildName());
+            }
+            return;
+        }
+        assert (!hasTxnInStack()) : "Who's rolling back transaction when there's still txn in stack?";
+        _txn = false;
+        try {
+            if (_conn != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Rolling back the transaction: Time = " + (System.currentTimeMillis() - _txnTime) + " Name =  " + _name + "; called by " + buildName());
+                }
+                _conn.rollback();
+            }
+            clearLockTimes();
+            closeConnection();
+        } catch(final SQLException e) {
+            s_logger.warn("Unable to rollback", e);
+        }
+    }
+
+    protected void rollbackSavepoint(Savepoint sp) {
+        try {
+            if (_conn != null) {
+                _conn.rollback(sp);
+            }
+        } catch (SQLException e) {
+            s_logger.warn("Unable to rollback to savepoint " + sp);
+        }
+
+        if (!hasTxnInStack()) {
+            _txn = false;
+            closeConnection();
+        }
+    }
+
+    public void rollback() {
+        Iterator<StackElement> it = _stack.iterator();
+        while (it.hasNext()) {
+            StackElement st = it.next();
+            if (st.type == START_TXN) {
+                if (st.ref == null) {
+                    it.remove();
+                } else  {
+                    rollback((Savepoint)st.ref);
+                    return;
+                }
+            }
+        }
+
+        rollbackTransaction();
+    }
+
+    public Savepoint setSavepoint() throws SQLException {
+        _txn = true;
+        StackElement st = new StackElement(START_TXN, null);
+        _stack.push(st);
+        final Connection conn = getConnection();
+        final Savepoint sp = conn.setSavepoint();
+        st.ref = sp;
+
+        return sp;
+    }
+
+    public Savepoint setSavepoint(final String name) throws SQLException {
+        _txn = true;
+        StackElement st = new StackElement(START_TXN, null);
+        _stack.push(st);
+        final Connection conn = getConnection();
+        final Savepoint sp = conn.setSavepoint(name);
+        st.ref = sp;
+
+        return sp;
+    }
+
+    public void releaseSavepoint(final Savepoint sp) throws SQLException {
+        removeTxn(sp);
+        if (_conn != null) {
+            _conn.releaseSavepoint(sp);
+        }
+
+        if (!hasTxnInStack()) {
+            _txn = false;
+            closeConnection();
+        }
+    }
+
+    protected boolean hasSavepointInStack(Savepoint sp) {
+        Iterator<StackElement> it = _stack.iterator();
+        while (it.hasNext()) {
+            StackElement se = it.next();
+            if (se.type == START_TXN && se.ref == sp) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected void removeTxn(Savepoint sp) {
+        assert hasSavepointInStack(sp) : "Removing a save point that's not in the stack";
+
+        if (!hasSavepointInStack(sp)) {
+            return;
+        }
+
+        Iterator<StackElement> it = _stack.iterator();
+        while (it.hasNext()) {
+            StackElement se = it.next();
+            if (se.type == START_TXN) {
+                it.remove();
+                if (se.ref == sp) {
+                    return;
+                }
+            }
+        }
+    }
+
+    public void rollback(final Savepoint sp) {
+        removeTxn(sp);
+
+        rollbackSavepoint(sp);
+    }
+
+    public Connection getCurrentConnection() {
+        return _conn;
+    }
+
+    public List<StackElement> getStack() {
+        return _stack;
+    }
+
+    protected Transaction() {
+        _name = null;
+        _conn = null;
+        _stack = null;
+        _txn = false;
+        _dbId = -1;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (!(_conn == null && (_stack == null || _stack.size() == 0))) {
+            assert (false) : "Oh Alex oh alex...something is wrong with how we're doing this";
+            s_logger.error("Something went wrong that a transaction is orphaned before db connection is closed");
+            cleanup();
+        }
+    }
+
+    protected class StackElement {
+        public String type;
+        public Object ref;
+
+        public StackElement (String type, Object ref) {
+            this.type = type;
+            this.ref = ref;
+        }
+
+        @Override
+        public String toString() {
+            return type + "-" + ref;
+        }
+    }
+
+    private static DataSource s_ds;
+    private static DataSource s_usageDS;
+    private static DataSource s_awsapiDS;
+    private static DataSource s_simulatorDS;
+
+    static {
+        // Initialize with assumed db.properties file
+        initDataSource("db.properties");
+    }
+
+    public static void initDataSource(String propsFileName) {
+        try {
+            File dbPropsFile = PropertiesUtil.findConfigFile(propsFileName);
+            final Properties dbProps;
+            if (EncryptionSecretKeyChecker.useEncryption()) {
+                StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
+                dbProps = new EncryptableProperties(encryptor);
+            } else {
+                dbProps = new Properties();
+            }
+            try {
+                dbProps.load(new FileInputStream(dbPropsFile));
+            } catch (IOException e) {
+                s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e);
+                return;
+            } catch (NullPointerException e) {
+                s_logger.fatal("Unable to locate db properties file within classpath or absolute path: " + propsFileName);
+                return;
+            }
+
+            // FIXME:  If params are missing...default them????
+            final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
+            final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle"));
+            final long cloudMaxWait = Long.parseLong(dbProps.getProperty("db.cloud.maxWait"));
+            final String cloudUsername = dbProps.getProperty("db.cloud.username");
+            final String cloudPassword = dbProps.getProperty("db.cloud.password");
+            final String cloudHost = dbProps.getProperty("db.cloud.host");
+            final int cloudPort = Integer.parseInt(dbProps.getProperty("db.cloud.port"));
+            final String cloudDbName = dbProps.getProperty("db.cloud.name");
+            final boolean cloudAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.cloud.autoReconnect"));
+            final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery");
+            final String cloudIsolationLevel = dbProps.getProperty("db.cloud.isolation.level");
+
+            int isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
+            if (cloudIsolationLevel == null) {
+                isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
+            } else if (cloudIsolationLevel.equalsIgnoreCase("readcommitted")) {
+                isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
+            } else if (cloudIsolationLevel.equalsIgnoreCase("repeatableread")) {
+                isolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
+            } else if (cloudIsolationLevel.equalsIgnoreCase("serializable")) {
+                isolationLevel = Connection.TRANSACTION_SERIALIZABLE;
+            } else if (cloudIsolationLevel.equalsIgnoreCase("readuncommitted")) {
+                isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
+            } else {
+                s_logger.warn("Unknown isolation level " + cloudIsolationLevel + ".  Using read uncommitted");
+            }
+
+            final boolean cloudTestOnBorrow = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testOnBorrow"));
+            final boolean cloudTestWhileIdle = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testWhileIdle"));
+            final long cloudTimeBtwEvictionRunsMillis = Long.parseLong(dbProps.getProperty("db.cloud.timeBetweenEvictionRunsMillis"));
+            final long cloudMinEvcitableIdleTimeMillis = Long.parseLong(dbProps.getProperty("db.cloud.minEvictableIdleTimeMillis"));
+            final boolean cloudPoolPreparedStatements = Boolean.parseBoolean(dbProps.getProperty("db.cloud.poolPreparedStatements"));
+            final String url = dbProps.getProperty("db.cloud.url.params");
+
+            final boolean useSSL = Boolean.parseBoolean(dbProps.getProperty("db.cloud.useSSL"));
+            if (useSSL) {
+                System.setProperty("javax.net.ssl.keyStore", dbProps.getProperty("db.cloud.keyStore"));
+                System.setProperty("javax.net.ssl.keyStorePassword", dbProps.getProperty("db.cloud.keyStorePassword"));
+                System.setProperty("javax.net.ssl.trustStore", dbProps.getProperty("db.cloud.trustStore"));
+                System.setProperty("javax.net.ssl.trustStorePassword", dbProps.getProperty("db.cloud.trustStorePassword"));
+            }
+
+            String regionId = dbProps.getProperty("region.id");
+            if(regionId == null){
+            	s_region_id = 1;
+            } else {
+            	s_region_id = Integer.parseInt(regionId);
+            }
+            final GenericObjectPool cloudConnectionPool = new GenericObjectPool(null, cloudMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
+                    cloudMaxWait, cloudMaxIdle, cloudTestOnBorrow, false, cloudTimeBtwEvictionRunsMillis, 1, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle);
+
+            final ConnectionFactory cloudConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + cloudDbName +
+                    "?autoReconnect=" + cloudAutoReconnect + (url != null ? "&" + url : "") + (useSSL ? "&useSSL=true" : ""), cloudUsername, cloudPassword);
+
+            final KeyedObjectPoolFactory poolableObjFactory = (cloudPoolPreparedStatements ? new StackKeyedObjectPoolFactory() : null);
+
+            final PoolableConnectionFactory cloudPoolableConnectionFactory = new PoolableConnectionFactory(cloudConnectionFactory, cloudConnectionPool, poolableObjFactory,
+                    cloudValidationQuery, false, false, isolationLevel);
+
+            // Default Data Source for CloudStack
+            s_ds = new PoolingDataSource(cloudPoolableConnectionFactory.getPool());
+
+            // Configure the usage db
+            final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive"));
+            final int usageMaxIdle = Integer.parseInt(dbProps.getProperty("db.usage.maxIdle"));
+            final long usageMaxWait = Long.parseLong(dbProps.getProperty("db.usage.maxWait"));
+            final String usageUsername = dbProps.getProperty("db.usage.username");
+            final String usagePassword = dbProps.getProperty("db.usage.password");
+            final String usageHost = dbProps.getProperty("db.usage.host");
+            final int usagePort = Integer.parseInt(dbProps.getProperty("db.usage.port"));
+            final String usageDbName = dbProps.getProperty("db.usage.name");
+            final boolean usageAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.usage.autoReconnect"));
+            final String usageUrl = dbProps.getProperty("db.usage.url.params");
+
+            final GenericObjectPool usageConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
+                    usageMaxWait, usageMaxIdle);
+
+            final ConnectionFactory usageConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + usageHost + ":" + usagePort + "/" + usageDbName +
+                    "?autoReconnect=" + usageAutoReconnect + (usageUrl != null ? "&" + usageUrl : ""), usageUsername, usagePassword);
+
+            final PoolableConnectionFactory usagePoolableConnectionFactory = new PoolableConnectionFactory(usageConnectionFactory, usageConnectionPool,
+                    new StackKeyedObjectPoolFactory(), null, false, false);
+
+            // Data Source for usage server
+            s_usageDS = new PoolingDataSource(usagePoolableConnectionFactory.getPool());
+
+            // Configure awsapi db
+            final String awsapiDbName = dbProps.getProperty("db.awsapi.name");
+            final GenericObjectPool awsapiConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
+                    usageMaxWait, usageMaxIdle);
+            final ConnectionFactory awsapiConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + awsapiDbName +
+                    "?autoReconnect=" + usageAutoReconnect, cloudUsername, cloudPassword);
+            final PoolableConnectionFactory awsapiPoolableConnectionFactory = new PoolableConnectionFactory(awsapiConnectionFactory, awsapiConnectionPool,
+                    new StackKeyedObjectPoolFactory(), null, false, false);
+
+            // Data Source for awsapi
+            s_awsapiDS = new PoolingDataSource(awsapiPoolableConnectionFactory.getPool());
+
+            try {
+                // Configure the simulator db
+                final int simulatorMaxActive = Integer.parseInt(dbProps.getProperty("db.simulator.maxActive"));
+                final int simulatorMaxIdle = Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle"));
+                final long simulatorMaxWait = Long.parseLong(dbProps.getProperty("db.simulator.maxWait"));
+                final String simulatorUsername = dbProps.getProperty("db.simulator.username");
+                final String simulatorPassword = dbProps.getProperty("db.simulator.password");
+                final String simulatorHost = dbProps.getProperty("db.simulator.host");
+                final int simulatorPort = Integer.parseInt(dbProps.getProperty("db.simulator.port"));
+                final String simulatorDbName = dbProps.getProperty("db.simulator.name");
+                final boolean simulatorAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.simulator.autoReconnect"));
+
+                final GenericObjectPool simulatorConnectionPool = new GenericObjectPool(null, simulatorMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
+                        simulatorMaxWait, simulatorMaxIdle);
+
+                final ConnectionFactory simulatorConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + simulatorHost + ":" + simulatorPort + "/" + simulatorDbName +
+                        "?autoReconnect=" + simulatorAutoReconnect, simulatorUsername, simulatorPassword);
+
+                final PoolableConnectionFactory simulatorPoolableConnectionFactory = new PoolableConnectionFactory(simulatorConnectionFactory, simulatorConnectionPool,
+                        new StackKeyedObjectPoolFactory(), null, false, false);
+                s_simulatorDS = new PoolingDataSource(simulatorPoolableConnectionFactory.getPool());
+            } catch (Exception e) {
+                s_logger.debug("Simulator DB properties are not available. Not initializing simulator DS");
+            }
+        } catch (final Exception e) {
+            s_ds = getDefaultDataSource("cloud");
+            s_usageDS = getDefaultDataSource("cloud_usage");
+            s_simulatorDS = getDefaultDataSource("cloud_simulator");
+            s_logger.warn("Unable to load db configuration, using defaults with 5 connections. Falling back on assumed datasource on localhost:3306 using username:password=cloud:cloud. Please check your configuration", e);
+        }
+    }
+
+    private static DataSource getDefaultDataSource(final String database) {
+        final GenericObjectPool connectionPool = new GenericObjectPool(null, 5);
+        final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
+           "jdbc:mysql://localhost:3306/" + database, "cloud", "cloud");
+        final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
+           connectionFactory, connectionPool, null, null, false, true);
+        return new PoolingDataSource(
+           /* connectionPool */poolableConnectionFactory.getPool());
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/TransactionAttachment.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/TransactionAttachment.java b/framework/db/src/com/cloud/utils/db/TransactionAttachment.java
new file mode 100644
index 0000000..198f74c
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/TransactionAttachment.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+/**
+ * TransactionAttachment are objects added to Transaction such that when
+ * the in memory transaction is closed, they are automatically closed.
+ *
+ */
+public interface TransactionAttachment {
+    /**
+     * @return a unique name to be inserted.
+     */
+    String getName();
+    
+    /**
+     * cleanup() if it wasn't cleaned up before.
+     */
+    void cleanup();
+}


[08/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/GenericSearchBuilder.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/GenericSearchBuilder.java b/framework/db/src/com/cloud/utils/db/GenericSearchBuilder.java
new file mode 100755
index 0000000..bf28144
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/GenericSearchBuilder.java
@@ -0,0 +1,548 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Transient;
+
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria.SelectType;
+
+/**
+ * GenericSearchBuilder is used to build a search based on a VO object
+ * a convenience class provided called SearchBuilder that provides
+ * exactly that functionality.
+ *
+ * @param <T> VO object this Search is build for.
+ * @param <K> Result object that should contain the results.
+ */
+public class GenericSearchBuilder<T, K> implements MethodInterceptor {
+    final protected Map<String, Attribute> _attrs;
+    
+    protected ArrayList<Condition> _conditions;
+    protected HashMap<String, JoinBuilder<GenericSearchBuilder<?, ?>>> _joins;
+    protected ArrayList<Select> _selects;
+    protected GroupBy<T, K> _groupBy = null;
+    protected Class<T> _entityBeanType;
+    protected Class<K> _resultType;
+    protected SelectType _selectType;
+    
+    protected T _entity;
+    protected ArrayList<Attribute> _specifiedAttrs;
+    
+    @SuppressWarnings("unchecked")
+    protected GenericSearchBuilder(T entity, Class<K> clazz, Map<String, Attribute> attrs) {
+        _entityBeanType = (Class<T>)entity.getClass();
+        _resultType = clazz;
+        
+        _attrs = attrs;
+        _entity = entity;
+        _conditions = new ArrayList<Condition>();
+        _joins = null;
+        _specifiedAttrs = new ArrayList<Attribute>();
+    }
+    
+    public T entity() {
+        return _entity;
+    }
+    
+    protected Attribute getSpecifiedAttribute() {
+        if (_entity == null || _specifiedAttrs == null || _specifiedAttrs.size() != 1) {
+            throw new RuntimeException("Now now, better specify an attribute or else we can't help you");
+        }
+        return _specifiedAttrs.get(0);
+    }
+
+    public GenericSearchBuilder<T, K> selectField(Object... useless) {
+        if (_entity == null) {
+            throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
+        }
+        if (_specifiedAttrs.size() <= 0) {
+            throw new RuntimeException("You didn't specify any attributes");
+        }
+   
+        if (_selects == null) {
+            _selects = new ArrayList<Select>();
+        }
+        
+        for (Attribute attr : _specifiedAttrs) {
+            Field field = null;
+            try {
+                field = _resultType.getDeclaredField(attr.field.getName());
+                field.setAccessible(true);
+            } catch (SecurityException e) {
+            } catch (NoSuchFieldException e) {
+            }
+            _selects.add(new Select(Func.NATIVE, attr, field, null));
+        }
+        
+        _specifiedAttrs.clear();
+        
+        return this;
+    }
+    
+//    public GenericSearchBuilder<T, K> selectField(String joinName, Object... entityFields) {
+//        JoinBuilder<GenericSearchBuilder<?, ?>> jb = _joins.get(joinName);
+//
+//    }
+    
+    /**
+     * Specifies the field to select.
+     * 
+     * @param fieldName The field name of the result object to put the value of the field selected.  This can be null if you're selecting only one field and the result is not a complex object.
+     * @param func function to place.
+     * @param useless column to select.  Call this with this.entity() method.
+     * @param params parameters to the function.
+     * @return a SearchBuilder to build more search parts.
+     */
+    public GenericSearchBuilder<T, K> select(String fieldName, Func func, Object useless, Object... params) {
+        if (_entity == null) {
+            throw new RuntimeException("SearchBuilder cannot be modified once it has been setup");
+        }
+        if (_specifiedAttrs.size() > 1) {
+            throw new RuntimeException("You can't specify more than one field to search on");
+        }
+        if (func.getCount() != -1 && (func.getCount() != (params.length + 1))) {
+            throw new RuntimeException("The number of parameters does not match the function param count for " + func);
+        }
+        
+        if (_selects == null) {
+            _selects = new ArrayList<Select>();
+        }
+        
+        Field field = null;
+        if (fieldName != null) {
+            try {
+                field = _resultType.getDeclaredField(fieldName);
+                field.setAccessible(true);
+            } catch (SecurityException e) {
+                throw new RuntimeException("Unable to find " + fieldName, e);
+            } catch (NoSuchFieldException e) {
+                throw new RuntimeException("Unable to find " + fieldName, e);
+            }
+        } else {
+            if (_selects.size() != 0) {
+                throw new RuntimeException(
+                        "You're selecting more than one item and yet is not providing a container class to put these items in.  So what do you expect me to do.  Spin magic?");
+            }
+        }
+        
+        Select select = new Select(func, _specifiedAttrs.size() == 0 ? null : _specifiedAttrs.get(0), field, params);
+        _selects.add(select);
+        
+        _specifiedAttrs.clear();
+        
+        return this;
+    }
+    
+    @Override
+    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
+        String name = method.getName();
+		if (method.getAnnotation(Transient.class) == null) {
+			if (name.startsWith("get")) {
+				String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+				set(fieldName);
+				return null;
+			} else if (name.startsWith("is")) {
+				String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
+				set(fieldName);
+				return null;
+			} else {
+			    Column ann = method.getAnnotation(Column.class);
+			    if (ann != null) {
+			        String colName = ann.name();
+			        for (Map.Entry<String, Attribute> attr : _attrs.entrySet()) {
+			            if (colName.equals(attr.getValue().columnName)) {
+			                set(attr.getKey());
+			                return null;
+			            }
+			        }
+			    }
+                throw new RuntimeException("Perhaps you need to make the method start with get or is: " + method);
+			}
+		}
+        return methodProxy.invokeSuper(object, args);
+    }
+    
+    protected void set(String name) {
+        Attribute attr = _attrs.get(name);
+        assert (attr != null) : "Searching for a field that's not there: " + name;
+        _specifiedAttrs.add(attr);
+    }
+   
+    /**
+     * Adds an AND condition to the SearchBuilder.
+     * 
+     * @param name param name you will use later to set the values in this search condition.
+     * @param useless SearchBuilder.entity().get*() which refers to the field that you're searching on.
+     * @param op operation to apply to the field.
+     * @return this
+     */
+    public GenericSearchBuilder<T, K> and(String name, Object useless, Op op) {
+        constructCondition(name, " AND ", _specifiedAttrs.get(0), op);
+        return this;
+    }
+    
+    public GenericSearchBuilder<T, K> and(Object useless, Op op, String name) {
+        constructCondition(name, " AND ", _specifiedAttrs.get(0), op);
+        return this;
+    }
+
+    public Preset and(Object useless, Op op) {
+        Condition condition = constructCondition(UUID.randomUUID().toString(), " AND ", _specifiedAttrs.get(0), op);
+        return new Preset(this, condition);
+    }
+
+    public GenericSearchBuilder<T, K> and() {
+        constructCondition(null, " AND ", null, null);
+        return this;
+    }
+    
+    public GenericSearchBuilder<T, K> where() {
+        return and();
+    }
+    
+    public GenericSearchBuilder<T, K> or() {
+        constructCondition(null, " OR ", null, null);
+        return this;
+    }
+    
+    public GenericSearchBuilder<T, K> where(String name, Object useless, Op op) {
+        return and(name, useless, op);
+    }
+    
+    public GenericSearchBuilder<T, K> where(Object useless, Op op, String name) {
+        return and(name, useless, op);
+    }
+
+    public Preset where(Object useless, Op op) {
+        return and(useless, op);
+    }
+
+    public GenericSearchBuilder<T, K> left(String name, Object useless, Op op) {
+        constructCondition(name, " ( ", _specifiedAttrs.get(0), op);
+        return this;
+    }
+    
+    public GenericSearchBuilder<T, K> left(Object useless, Op op, String name) {
+        constructCondition(name, " ( ", _specifiedAttrs.get(0), op);
+        return this;
+    }
+
+    public Preset left(Object useless, Op op) {
+        Condition condition = constructCondition(UUID.randomUUID().toString(), " ( ", _specifiedAttrs.get(0), op);
+        return new Preset(this, condition);
+    }
+
+    public GenericSearchBuilder<T, K> op(Object useless, Op op, String name) {
+        return left(useless, op, name);
+    }
+
+    public Preset op(Object useless, Op op) {
+        return left(useless, op);
+    }
+
+    public GenericSearchBuilder<T, K> op(String name, Object useless, Op op) {
+        return left(name, useless, op);
+    }
+    
+    public GenericSearchBuilder<T, K> openParen(Object useless, Op op, String name) {
+        return left(name, useless, op);
+    }
+
+    public GenericSearchBuilder<T, K> openParen(String name, Object useless, Op op) {
+        return left(name, useless, op);
+    }
+    
+    public Preset openParen(Object useless, Op op) {
+        return left(useless, op);
+    }
+
+    public GroupBy<T, K> groupBy(Object... useless) {
+        assert _groupBy == null : "Can't do more than one group bys";
+        _groupBy = new GroupBy<T, K>(this);
+        
+        return _groupBy;
+    }
+    
+    protected List<Attribute> getSpecifiedAttributes() {
+        return _specifiedAttrs;
+    }
+    
+    /**
+     * Adds an OR condition to the SearchBuilder.
+     * 
+     * @param name param name you will use later to set the values in this search condition.
+     * @param useless SearchBuilder.entity().get*() which refers to the field that you're searching on.
+     * @param op operation to apply to the field.
+     * @return this
+     */
+    public GenericSearchBuilder<T, K> or(String name, Object useless, Op op) {
+        constructCondition(name, " OR ", _specifiedAttrs.get(0), op);
+        return this;
+    }
+    
+    public GenericSearchBuilder<T, K> or(Object useless, Op op, String name) {
+        constructCondition(name, " OR ", _specifiedAttrs.get(0), op);
+        return this;
+    }
+
+    public Preset or(Object useless, Op op) {
+        Condition condition = constructCondition(UUID.randomUUID().toString(), " OR ", _specifiedAttrs.get(0), op);
+        return new Preset(this, condition);
+    }
+
+    public GenericSearchBuilder<T, K> join(String name, GenericSearchBuilder<?, ?> builder, Object useless, Object useless2, JoinBuilder.JoinType joinType) {
+        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
+        assert _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
+        assert builder._entity != null : "SearchBuilder cannot be modified once it has been setup";
+        assert builder._specifiedAttrs.size() == 1 : "You didn't select the attribute.";
+        assert builder != this : "You can't add yourself, can you?  Really think about it!";
+        
+        JoinBuilder<GenericSearchBuilder<?, ?>> t = new JoinBuilder<GenericSearchBuilder<?, ?>>(builder, _specifiedAttrs.get(0), builder._specifiedAttrs.get(0), joinType);
+        if (_joins == null) {
+        	_joins = new HashMap<String, JoinBuilder<GenericSearchBuilder<?, ?>>>();
+        }
+        _joins.put(name, t);
+        
+        builder._specifiedAttrs.clear();
+        _specifiedAttrs.clear();
+        return this;
+    }
+    
+    protected Condition constructCondition(String conditionName, String cond, Attribute attr, Op op) {
+        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
+        assert op == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
+        assert op != Op.SC : "Call join";
+        
+        Condition condition = new Condition(conditionName, cond, attr, op);
+        _conditions.add(condition);
+        _specifiedAttrs.clear();
+        return condition;
+    }
+
+    /**
+     * creates the SearchCriteria so the actual values can be filled in.
+     * 
+     * @return SearchCriteria
+     */
+    public SearchCriteria<K> create() {
+        if (_entity != null) {
+            done();
+        }
+        return new SearchCriteria<K>(this);
+    }
+    
+    public SearchCriteria<K> create(String name, Object... values) {
+        SearchCriteria<K> sc = create();
+        sc.setParameters(name, values);
+        return sc;
+    }
+    
+    public GenericSearchBuilder<T, K> right() {
+        Condition condition = new Condition("rp", " ) ", null, Op.RP);
+        _conditions.add(condition);
+        return this;
+    }
+    
+    public GenericSearchBuilder<T, K> cp() {
+        return right();
+    }
+    
+    public GenericSearchBuilder<T, K> closeParen() {
+        return right();
+    }
+    
+    public SelectType getSelectType() {
+        return _selectType;
+    }
+    
+    /**
+     * Marks the SearchBuilder as completed in building the search conditions.
+     */
+    public synchronized void done() {
+        if (_entity != null) {
+            Factory factory = (Factory)_entity;
+            factory.setCallback(0, null);
+            _entity = null;
+        }
+        
+        if (_joins != null) {
+        	for (JoinBuilder<GenericSearchBuilder<?, ?>> join : _joins.values()) {
+        		join.getT().done();
+            }
+        }
+        
+        if (_selects == null || _selects.size() == 0) {
+            _selectType = SelectType.Entity;
+            assert _entityBeanType.equals(_resultType) : "Expecting " + _entityBeanType + " because you didn't specify any selects but instead got " + _resultType;
+            return;
+        }
+        
+        for (Select select : _selects) {
+            if (select.field == null) {
+                assert (_selects.size() == 1) : "You didn't specify any fields to put the result in but you're specifying more than one select so where should I put the selects?";
+                _selectType = SelectType.Single;
+                return;
+            }
+            if (select.func != null) {
+                _selectType = SelectType.Result;
+                return;
+            }
+        }
+        
+        _selectType = SelectType.Fields;
+    }
+    
+    protected static class Condition {
+        protected final String name;
+        protected final String cond;
+        protected final Op op;
+        protected final Attribute attr;
+        protected Object[] presets;
+        
+        protected Condition(String name) {
+            this(name, null, null, null);
+        }
+        
+        public Condition(String name, String cond, Attribute attr, Op op) {
+            this.name = name;
+            this.attr = attr;
+            this.cond = cond;
+            this.op = op;
+            this.presets = null;
+        }
+        
+        public boolean isPreset() {
+            return presets != null;
+        }
+
+        public void setPresets(Object... presets) {
+            this.presets = presets;
+        }
+
+        public Object[] getPresets() {
+            return presets;
+        }
+
+        public void toSql(StringBuilder sql, Object[] params, int count) {
+            if (count > 0) {
+                sql.append(cond);
+            }
+            
+            if (op == null) {
+                return;
+            }
+            
+            if (op == Op.SC) {
+                sql.append(" (").append(((SearchCriteria<?>)params[0]).getWhereClause()).append(") ");
+                return;
+            }
+            
+            if (attr == null) {
+                return;
+            }
+            
+            sql.append(attr.table).append(".").append(attr.columnName).append(op.toString());
+            if (op == Op.IN && params.length == 1) {
+                sql.delete(sql.length() - op.toString().length(), sql.length());
+                sql.append("=?");
+            } else if (op == Op.NIN && params.length == 1) {
+                sql.delete(sql.length() - op.toString().length(), sql.length());
+                sql.append("!=?");
+            } else if (op.getParams() == -1) {
+                for (int i = 0; i < params.length; i++) {
+                    sql.insert(sql.length() - 2, "?,");
+                }
+                sql.delete(sql.length() - 3, sql.length() - 2); // remove the last ,
+            } else if (op  == Op.EQ && (params == null || params.length == 0 || params[0] == null)) {
+                sql.delete(sql.length() - 4, sql.length());
+                sql.append(" IS NULL ");
+            } else if (op == Op.NEQ && (params == null || params.length == 0 || params[0] == null)) {
+                sql.delete(sql.length() - 5, sql.length());
+                sql.append(" IS NOT NULL ");
+            } else {
+                if ((op.getParams() != 0 || params != null) && (params.length != op.getParams())) {
+                    throw new RuntimeException("Problem with condition: " + name);
+                }
+            }
+        }
+        
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof Condition)) {
+                return false;
+            }
+            
+            Condition condition = (Condition)obj;
+            return name.equals(condition.name);
+        }
+    }
+    
+    protected static class Select {
+        public Func func;
+        public Attribute attr;
+        public Object[] params;
+        public Field field;
+        
+        protected Select() {
+        }
+        
+        public Select(Func func, Attribute attr, Field field, Object[] params) {
+            this.func = func;
+            this.attr = attr;
+            this.params = params;
+            this.field = field;
+        }
+    }
+    
+    public class Preset {
+        GenericSearchBuilder<T, K> builder;
+        Condition condition;
+
+        protected Preset(GenericSearchBuilder<T, K> builder, Condition condition) {
+            this.builder = builder;
+            this.condition = condition;
+        }
+
+        public GenericSearchBuilder<T, K> values(Object... params) {
+            if (condition.op.getParams() > 0 && condition.op.params != params.length) {
+                throw new RuntimeException("The # of parameters set " + params.length + " does not match # of parameters required by " + condition.op);
+            }
+            condition.setPresets(params);
+            return builder;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/GlobalLock.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/GlobalLock.java b/framework/db/src/com/cloud/utils/db/GlobalLock.java
new file mode 100644
index 0000000..c956bbf
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/GlobalLock.java
@@ -0,0 +1,244 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import static java.lang.String.format;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.Profiler;
+
+//
+// Wrapper class for global database lock to reduce contention for database connections from within process
+//
+// Example of using dynamic named locks
+//
+//		GlobalLock lock = GlobalLock.getInternLock("some table name" + rowId);
+//		
+//		if(lock.lock()) {
+//			try {
+//				do something
+//			} finally {
+//				lock.unlock();
+//			}
+//		}
+//		lock.releaseRef();
+//
+public class GlobalLock {
+    protected final static Logger s_logger = Logger.getLogger(GlobalLock.class);
+
+	private String name;
+	private int lockCount = 0;
+	private Thread ownerThread = null;
+	
+	private int referenceCount = 0;
+	private long holdingStartTick = 0;
+	
+	private static Map<String, GlobalLock> s_lockMap = new HashMap<String, GlobalLock>();
+	
+	private GlobalLock(String name) {
+		this.name = name;
+	}
+	
+	public int addRef() {
+		synchronized(this) {
+			referenceCount++;
+			return referenceCount;
+		}
+	}
+	
+	public int releaseRef() {
+		int refCount;
+		
+		boolean needToRemove = false;
+		synchronized(this) {
+			referenceCount--;
+			refCount = referenceCount;
+			
+			if(referenceCount < 0)
+				s_logger.warn("Unmatched Global lock " + name + " reference usage detected, check your code!");
+			
+			if(referenceCount == 0)
+				needToRemove = true;
+		}
+		
+		if(needToRemove)
+			releaseInternLock(name);
+		
+		return refCount;
+	}
+
+	public static GlobalLock getInternLock(String name) {
+		synchronized(s_lockMap) {
+			if(s_lockMap.containsKey(name)) {
+				GlobalLock lock = s_lockMap.get(name);
+				lock.addRef();
+				return lock;
+			} else {
+				GlobalLock lock = new GlobalLock(name);
+				lock.addRef();
+				s_lockMap.put(name, lock);
+				return lock;
+			}
+		}
+	}
+	
+	private static void releaseInternLock(String name) {
+		synchronized(s_lockMap) {
+			GlobalLock lock = s_lockMap.get(name);
+			if(lock != null) {
+				if(lock.referenceCount == 0)
+					s_lockMap.remove(name);
+			} else {
+				s_logger.warn("Releasing " + name + ", but it is already released.");
+			}
+		}
+	}
+	
+	public boolean lock(int timeoutSeconds) {
+		int remainingMilliSeconds = timeoutSeconds*1000;
+		Profiler profiler = new Profiler();
+		boolean interrupted = false;
+		try {
+			while(true) {
+				synchronized(this) {
+					if(ownerThread != null && ownerThread == Thread.currentThread()) {
+						s_logger.warn("Global lock re-entrance detected");
+						
+						lockCount++;
+	
+						if(s_logger.isTraceEnabled())
+							s_logger.trace("lock " + name + " is acquired, lock count :" + lockCount);
+						return true;
+					}
+					
+					if(ownerThread != null) {
+						profiler.start();
+						try {
+							wait(((long)timeoutSeconds)*1000L);
+						} catch (InterruptedException e) {
+							interrupted = true;
+						}
+						profiler.stop();
+						
+						remainingMilliSeconds -= profiler.getDuration();
+						if(remainingMilliSeconds < 0)
+							return false;
+						
+						continue;
+					} else {
+						// take ownership temporarily to prevent others enter into stage of acquiring DB lock
+						ownerThread = Thread.currentThread();
+						addRef();
+					}
+				}
+
+				if(DbUtil.getGlobalLock(name, remainingMilliSeconds / 1000)) {
+					synchronized(this) {
+						lockCount++;
+						holdingStartTick = System.currentTimeMillis();
+						
+						if(s_logger.isTraceEnabled())
+							s_logger.trace("lock " + name + " is acquired, lock count :" + lockCount);
+						return true;
+					}
+				} else {
+					synchronized(this) {
+						ownerThread = null;
+						releaseRef();
+						return false;
+					}
+				}
+			}
+		} finally {
+			if(interrupted) {
+				Thread.currentThread().interrupt();
+			}
+		}
+	}
+	
+	public boolean unlock() {
+		synchronized(this) {
+			if(ownerThread != null && ownerThread == Thread.currentThread()) {
+				lockCount--;
+				if(lockCount == 0) {
+					ownerThread = null;
+					DbUtil.releaseGlobalLock(name);
+					
+					if(s_logger.isTraceEnabled())
+						s_logger.trace("lock " + name + " is returned to free state, total holding time :" + 
+							(System.currentTimeMillis() - holdingStartTick));
+					holdingStartTick = 0;
+					
+					// release holding position in intern map when we released the DB connection
+					releaseRef();
+					notifyAll();
+				}
+				
+				if(s_logger.isTraceEnabled())
+					s_logger.trace("lock " + name + " is released, lock count :" + lockCount);
+				return true;
+			}
+			return false;
+		}
+	}
+	
+	public String getName() {
+		return name;
+	}
+
+    public static <T> T executeWithLock(final String operationId,
+            final int lockAcquisitionTimeout, final Callable<T> operation)
+            throws Exception {
+
+        final GlobalLock lock = GlobalLock.getInternLock(operationId);
+
+        try {
+
+            if (!lock.lock(lockAcquisitionTimeout)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(format(
+                            "Failed to acquire lock for operation id %1$s",
+                            operationId));
+                }
+                return null;
+            }
+
+            return operation.call();
+
+        } finally {
+
+            if (lock != null) {
+                lock.unlock();
+            }
+
+        }
+
+    }
+
+    public static <T> T executeWithNoWaitLock(final String operationId,
+            final Callable<T> operation) throws Exception {
+
+        return executeWithLock(operationId, 0, operation);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/GroupBy.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/GroupBy.java b/framework/db/src/com/cloud/utils/db/GroupBy.java
new file mode 100644
index 0000000..3b9cd19
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/GroupBy.java
@@ -0,0 +1,108 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+public class GroupBy<T, R> {
+    GenericSearchBuilder<T, R> _builder;
+    List<Pair<Func, Attribute>> _groupBys;
+    Having _having;
+    
+    public GroupBy(GenericSearchBuilder<T, R> builder) {
+        _builder = builder;
+        _groupBys = new ArrayList<Pair<Func, Attribute>>();
+        _having = null;
+        for (Attribute attr : _builder.getSpecifiedAttributes()) {
+            _groupBys.add(new Pair<Func, Attribute>(null, attr));
+        }
+        _builder.getSpecifiedAttributes().clear();
+    }
+    
+    public GroupBy<T, R> group(Object useless) {
+        _groupBys.add(new Pair<Func, Attribute>(null, _builder.getSpecifiedAttributes().get(0)));
+        _builder.getSpecifiedAttributes().clear();
+        return this; 
+    }
+    
+    public GroupBy<T, R> group(Func func, Object useless) {
+        _groupBys.add(new Pair<Func, Attribute>(func, _builder.getSpecifiedAttributes().get(0)));
+        _builder.getSpecifiedAttributes().clear();
+        return this;
+    }
+    
+    public GenericSearchBuilder<T, R> having(Func func, Object obj, Op op, Object value) {
+        assert(_having == null) : "You can only specify one having in a group by";
+        List<Attribute> attrs = _builder.getSpecifiedAttributes();
+        assert attrs.size() == 1 : "You didn't specified an attribute";
+        
+        _having = new Having(func, attrs.get(0), op, value);
+        _builder.getSpecifiedAttributes().clear();
+        return _builder;
+    }
+    
+    public void toSql(StringBuilder builder) {
+        builder.append(" GROUP BY ");
+        for (Pair<Func, Attribute> groupBy : _groupBys) {
+            if (groupBy.first() != null) {
+                String func = groupBy.first().toString();
+                func.replaceFirst("@", groupBy.second().table + "." + groupBy.second().columnName);
+                builder.append(func);
+            } else {
+                builder.append(groupBy.second().table + "." + groupBy.second().columnName);
+            }
+            
+            builder.append(", ");
+        }
+        
+        builder.delete(builder.length() - 2, builder.length());
+        if (_having != null) {
+            _having.toSql(builder);
+        }
+    }
+    
+    protected class Having {
+        public Func func;
+        public Attribute attr;
+        public Op op;
+        public Object value;
+        
+        public Having(Func func, Attribute attr, Op op, Object value) {
+            this.func = func;
+            this.attr = attr;
+            this.op = op;
+            this.value = value;
+        }
+        
+        public void toSql(StringBuilder builder) {
+            if (func != null) {
+                String f = func.toString();
+                f.replaceFirst("@", attr.toString());
+                builder.append(func);
+            } else {
+                builder.append(attr.toString());
+            }
+            
+            builder.append(op.toString());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/JoinBuilder.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/JoinBuilder.java b/framework/db/src/com/cloud/utils/db/JoinBuilder.java
new file mode 100644
index 0000000..c4920c4
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/JoinBuilder.java
@@ -0,0 +1,79 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+
+public class JoinBuilder<T> {
+	
+	public enum JoinType {
+	     INNER ("INNER JOIN"),
+	     LEFT ("LEFT JOIN"),
+	     RIGHT ("RIGHT JOIN"),
+	     RIGHTOUTER ("RIGHT OUTER JOIN"),
+	     LEFTOUTER ("LEFT OUTER JOIN");
+	     
+	     private final String _name;
+	     
+	     JoinType(String name) {
+	            _name = name;
+	     }
+	     
+	     public String getName() { return _name; }
+	}
+
+	
+	private T t;
+	private JoinType type;
+	private Attribute firstAttribute;
+	private Attribute secondAttribute;
+	
+	public JoinBuilder(T t, Attribute firstAttribute,
+			Attribute secondAttribute, JoinType type) {
+		this.t = t;
+		this.firstAttribute = firstAttribute;
+		this.secondAttribute = secondAttribute;
+		this.type = type;
+	}
+	
+	public T getT() {
+		return t;
+	}
+	public void setT(T t) {
+		this.t = t;
+	}
+	public JoinType getType() {
+		return type;
+	}
+	public void setType(JoinType type) {
+		this.type = type;
+	}
+	public Attribute getFirstAttribute() {
+		return firstAttribute;
+	}
+	public void setFirstAttribute(Attribute firstAttribute) {
+		this.firstAttribute = firstAttribute;
+	}
+	public Attribute getSecondAttribute() {
+		return secondAttribute;
+	}
+	public void setSecondAttribute(Attribute secondAttribute) {
+		this.secondAttribute = secondAttribute;
+	}
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/JoinType.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/JoinType.java b/framework/db/src/com/cloud/utils/db/JoinType.java
new file mode 100755
index 0000000..6861925
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/JoinType.java
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * JoinType is only used with SecondaryTable.  Temporary solution.   
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+public @interface JoinType {
+    String type() default "inner";
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/Merovingian2.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/Merovingian2.java b/framework/db/src/com/cloud/utils/db/Merovingian2.java
new file mode 100644
index 0000000..0e0e8f2
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/Merovingian2.java
@@ -0,0 +1,461 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import javax.management.StandardMBean;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.mgmt.JmxUtil;
+import com.cloud.utils.time.InaccurateClock;
+
+
+public class Merovingian2 extends StandardMBean implements MerovingianMBean {
+    private static final Logger s_logger = Logger.getLogger(Merovingian2.class);
+
+    private static final String ACQUIRE_SQL = "INSERT INTO op_lock (op_lock.key, op_lock.mac, op_lock.ip, op_lock.thread, op_lock.acquired_on, waiters) VALUES (?, ?, ?, ?, ?, 1)";
+    private static final String INCREMENT_SQL = "UPDATE op_lock SET waiters=waiters+1 where op_lock.key=? AND op_lock.mac=? AND op_lock.ip=? AND op_lock.thread=?";
+    private static final String SELECT_SQL = "SELECT op_lock.key, mac, ip, thread, acquired_on, waiters FROM op_lock";
+    private static final String INQUIRE_SQL = SELECT_SQL + " WHERE op_lock.key=?";
+    private static final String DECREMENT_SQL = "UPDATE op_lock SET waiters=waiters-1 where op_lock.key=? AND op_lock.mac=? AND op_lock.ip=? AND op_lock.thread=?";
+    private static final String RELEASE_LOCK_SQL = "DELETE FROM op_lock WHERE op_lock.key = ?";
+    private static final String RELEASE_SQL = RELEASE_LOCK_SQL + " AND op_lock.mac=? AND waiters=0";
+    private static final String CLEANUP_MGMT_LOCKS_SQL = "DELETE FROM op_lock WHERE op_lock.mac = ?";
+    private static final String SELECT_MGMT_LOCKS_SQL = SELECT_SQL + " WHERE mac=?";
+    private static final String SELECT_THREAD_LOCKS_SQL = SELECT_SQL + " WHERE mac=? AND ip=?";
+    private static final String CLEANUP_THREAD_LOCKS_SQL = "DELETE FROM op_lock WHERE mac=? AND ip=? AND thread=?";
+
+    TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
+
+    private final long _msId;
+
+    private static Merovingian2 s_instance = null;
+    private ConnectionConcierge _concierge = null;
+    private static ThreadLocal<Count> s_tls = new ThreadLocal<Count>();
+
+    private Merovingian2(long msId) {
+        super(MerovingianMBean.class, false);
+        _msId = msId;
+        Connection conn = null;
+        try {
+            conn = Transaction.getStandaloneConnectionWithException();
+            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
+            conn.setAutoCommit(true);
+            _concierge = new ConnectionConcierge("LockMaster", conn, true);
+        } catch (SQLException e) {
+            s_logger.error("Unable to get a new db connection", e);
+            throw new CloudRuntimeException("Unable to initialize a connection to the database for locking purposes: ", e);
+        }
+    }
+
+    public static synchronized Merovingian2 createLockMaster(long msId) {
+        assert s_instance == null : "No lock can serve two masters.  Either he will hate the one and love the other, or he will be devoted to the one and despise the other.";
+        s_instance = new Merovingian2(msId);
+        s_instance.cleanupThisServer();
+        try {
+            JmxUtil.registerMBean("Locks", "Locks", s_instance);
+        } catch (Exception e) {
+            s_logger.error("Unable to register for JMX", e);
+        }
+        return s_instance;
+    }
+
+    public static Merovingian2 getLockMaster() {
+        return s_instance;
+    }
+
+
+    protected void incrCount() {
+        Count count = s_tls.get();
+        if (count == null) {
+            count = new Count();
+            s_tls.set(count);
+        }
+
+        count.count++;
+    }
+
+    protected void decrCount() {
+        Count count = s_tls.get();
+        if (count == null) {
+            return;
+        }
+
+        count.count--;
+    }
+
+
+    public boolean acquire(String key, int timeInSeconds) {
+        Thread th = Thread.currentThread();
+        String threadName = th.getName();
+        int threadId = System.identityHashCode(th);
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Acquiring lck-" + key + " with wait time of " + timeInSeconds);
+        }
+        long startTime = InaccurateClock.getTime();
+
+        while ((InaccurateClock.getTime() - startTime) < (timeInSeconds * 1000)) {
+            int count = owns(key);
+
+            if (count >= 1) {
+                return increment(key, threadName, threadId);
+            } else if (count == 0) {
+                if (doAcquire(key, threadName, threadId)) {
+                    return true;
+                }
+            }
+            try {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Sleeping more time while waiting for lck-" + key);
+                }
+                Thread.sleep(5000);
+            } catch (InterruptedException e) {
+            }
+        }
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Timed out on acquiring lock " + key + ".  Waited for " + (InaccurateClock.getTime() - startTime));
+        }
+        return false;
+    }
+
+    protected boolean increment(String key, String threadName, int threadId) {
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = _concierge.conn().prepareStatement(INCREMENT_SQL);
+            pstmt.setString(1, key);
+            pstmt.setLong(2, _msId);
+            pstmt.setString(3, threadName);
+            pstmt.setInt(4, threadId);
+            int rows = pstmt.executeUpdate();
+            assert (rows <= 1) : "hmm...non unique key? " + pstmt;
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("lck-" + key + (rows == 1 ? " acquired again" : " failed to acquire again"));
+            }
+            if (rows == 1) {
+                incrCount();
+                return true;
+            }
+            return false;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to increment " + key, e);
+        } finally {
+            try {
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+    }
+
+    protected boolean doAcquire(String key, String threadName, int threadId) {
+        PreparedStatement pstmt = null;
+
+        long startTime = InaccurateClock.getTime();
+        try {
+            pstmt = _concierge.conn().prepareStatement(ACQUIRE_SQL);
+            pstmt.setString(1, key);
+            pstmt.setLong(2, _msId);
+            pstmt.setString(3, threadName);
+            pstmt.setInt(4, threadId);
+            pstmt.setString(5, DateUtil.getDateDisplayString(s_gmtTimeZone, new Date()));
+            try {
+                int rows = pstmt.executeUpdate();
+                if (rows == 1) {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Acquired for lck-" + key);
+                    }
+                    incrCount();
+                    return true;
+                }
+            } catch(SQLException e) {
+                if (!(e.getSQLState().equals("23000") && e.getErrorCode() == 1062)) {
+                    throw new CloudRuntimeException("Unable to lock " + key + ".  Waited " + (InaccurateClock.getTime() - startTime), e);
+                }
+            }
+        } catch(SQLException e) {
+            throw new CloudRuntimeException("Unable to lock " + key + ".  Waited " + (InaccurateClock.getTime() - startTime), e);
+        } finally {
+            try {
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+
+        s_logger.trace("Unable to acquire lck-" + key);
+        return false;
+    }
+
+    protected Map<String, String> isLocked(String key) {
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        try {
+            pstmt = _concierge.conn().prepareStatement(INQUIRE_SQL);
+            pstmt.setString(1, key);
+            rs = pstmt.executeQuery();
+            if (!rs.next()) {
+                return null;
+            }
+
+            return toLock(rs);
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("SQL Exception on inquiry", e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+                s_logger.warn("Unexpected SQL exception " + e.getMessage(), e);
+            }
+        }
+    }
+
+    public void cleanupThisServer() {
+        cleanupForServer(_msId);
+    }
+
+    @Override
+    public void cleanupForServer(long msId) {
+        s_logger.info("Cleaning up locks for " + msId);
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = _concierge.conn().prepareStatement(CLEANUP_MGMT_LOCKS_SQL);
+            pstmt.setLong(1, msId);
+            int rows = pstmt.executeUpdate();
+            s_logger.info("Released " + rows + " locks for " + msId);
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to clear the locks", e);
+        } finally {
+            try {
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+    }
+
+    public boolean release(String key) {
+        PreparedStatement pstmt = null;
+        Thread th = Thread.currentThread();
+        String threadName = th.getName();
+        int threadId = System.identityHashCode(th);
+        try {
+            pstmt = _concierge.conn().prepareStatement(DECREMENT_SQL);
+            pstmt.setString(1, key);
+            pstmt.setLong(2, _msId);
+            pstmt.setString(3, threadName);
+            pstmt.setLong(4, threadId);
+            int rows = pstmt.executeUpdate();
+            assert (rows <= 1) : "hmmm....keys not unique? " + pstmt;
+           
+            
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("lck-" + key + " released");
+            }
+            if (rows == 1) {
+                pstmt.close();
+                pstmt = _concierge.conn().prepareStatement(RELEASE_SQL);
+                pstmt.setString(1, key);
+                pstmt.setLong(2, _msId);
+                int result = pstmt.executeUpdate();
+                if (result == 1 && s_logger.isTraceEnabled()) {
+                    s_logger.trace("lck-" + key + " removed");
+                }
+                decrCount();
+            } else  if (rows < 1) {
+                s_logger.warn("Was unable to find lock for the key " + key + " and thread id " + threadId);
+            }
+            
+            return rows == 1;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to release " + key, e);
+        } finally {
+            try {
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+    }
+
+    protected Map<String, String> toLock(ResultSet rs) throws SQLException {
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("key", rs.getString(1));
+        map.put("mgmt", rs.getString(2));
+        map.put("name", rs.getString(3));
+        map.put("tid", Integer.toString(rs.getInt(4)));
+        map.put("date", rs.getString(5));
+        map.put("count", Integer.toString(rs.getInt(6)));
+        return map;
+
+    }
+
+    protected List<Map<String, String>> toLocks(ResultSet rs) throws SQLException {
+        LinkedList<Map<String, String>> results = new LinkedList<Map<String, String>>();
+        while (rs.next()) {
+            results.add(toLock(rs));
+        }
+        return results;
+    }
+
+    protected List<Map<String, String>> getLocks(String sql, Long msId) {
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        try {
+            pstmt = _concierge.conn().prepareStatement(sql);
+            if (msId != null) {
+                pstmt.setLong(1, msId);
+            }
+            rs = pstmt.executeQuery();
+            return toLocks(rs);
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to retrieve locks ", e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch(SQLException e) {
+            }
+        }
+    }
+
+    @Override
+    public List<Map<String, String>> getAllLocks() {
+        return getLocks(SELECT_SQL, null);
+    }
+
+    @Override
+    public List<Map<String, String>> getLocksAcquiredByThisServer() {
+        return getLocks(SELECT_MGMT_LOCKS_SQL, _msId);
+    }
+
+    public int owns(String key) {
+        Thread th = Thread.currentThread();
+        int threadId = System.identityHashCode(th);
+        Map<String, String> owner = isLocked(key);
+        if (owner == null) {
+            return 0;
+        }
+        if (owner.get("mgmt").equals(Long.toString(_msId)) && owner.get("tid").equals(Integer.toString(threadId))) {
+            return Integer.parseInt(owner.get("count"));
+        }
+        return -1;
+    }
+
+    public List<Map<String, String>> getLocksAcquiredBy(long msId, String threadName) {
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        try {
+            pstmt = _concierge.conn().prepareStatement(SELECT_THREAD_LOCKS_SQL);
+            pstmt.setLong(1, msId);
+            pstmt.setString(2, threadName);
+            rs = pstmt.executeQuery();
+            return toLocks(rs);
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Can't get locks " + pstmt, e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+    }
+
+    public void cleanupThread() {
+
+        Count count = s_tls.get();
+        if (count == null || count.count == 0) {
+            return;
+        }
+
+        int c = count.count;
+
+        count.count = 0;
+
+        Thread th = Thread.currentThread();
+        String threadName = th.getName();
+        int threadId = System.identityHashCode(th);
+
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = _concierge.conn().prepareStatement(CLEANUP_THREAD_LOCKS_SQL);
+            pstmt.setLong(1, _msId);
+            pstmt.setString(2, threadName);
+            pstmt.setInt(3, threadId);
+            int rows = pstmt.executeUpdate();
+            assert (false) : "Abandon hope, all ye who enter here....There were still " + rows + ":" + c + " locks not released when the transaction ended, check for lock not released or @DB is not added to the code that using the locks!";
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Can't clear locks " + pstmt, e);
+        } finally {
+            try {
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+    }
+
+    @Override
+    public boolean releaseLockAsLastResortAndIReallyKnowWhatIAmDoing(String key) {
+        s_logger.info("Releasing a lock from JMX lck-" + key);
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = _concierge.conn().prepareStatement(RELEASE_LOCK_SQL);
+            pstmt.setString(1, key);
+            int rows = pstmt.executeUpdate();
+            return rows > 0;
+        } catch (SQLException e) {
+            s_logger.error("Unable to release lock " + key, e);
+            return false;
+        }
+    }
+    protected static class Count {
+        public int count = 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/MerovingianMBean.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/MerovingianMBean.java b/framework/db/src/com/cloud/utils/db/MerovingianMBean.java
new file mode 100644
index 0000000..e9ee955
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/MerovingianMBean.java
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.util.List;
+import java.util.Map;
+
+
+public interface MerovingianMBean {
+    
+    List<Map<String, String>> getAllLocks();
+    
+    List<Map<String, String>> getLocksAcquiredByThisServer();
+    
+    boolean releaseLockAsLastResortAndIReallyKnowWhatIAmDoing(String key);
+    
+    void cleanupForServer(long msId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/ScriptRunner.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/ScriptRunner.java b/framework/db/src/com/cloud/utils/db/ScriptRunner.java
new file mode 100644
index 0000000..d579de7
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/ScriptRunner.java
@@ -0,0 +1,233 @@
+/*
+ * Slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class
+ * from the iBATIS Apache project. Only removed dependency on Resource class
+ * and a constructor 
+ */
+/*
+ *  Copyright 2004 Clinton Begin
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.cloud.utils.db;
+
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Tool to run database scripts
+ */
+public class ScriptRunner {
+    private static Logger s_logger = Logger.getLogger(ScriptRunner.class); 
+
+    private static final String DEFAULT_DELIMITER = ";";
+
+    private Connection connection;
+
+    private boolean stopOnError;
+    private boolean autoCommit;
+    private boolean verbosity = true;
+
+    private String delimiter = DEFAULT_DELIMITER;
+    private boolean fullLineDelimiter = false;
+
+    private StringBuffer _logBuffer = new StringBuffer();
+
+    /**
+     * Default constructor
+     */
+    public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) {
+        this.connection = connection;
+        this.autoCommit = autoCommit;
+        this.stopOnError = stopOnError;
+    }
+
+    public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError, boolean verbosity) {
+        this.connection = connection;
+        this.autoCommit = autoCommit;
+        this.stopOnError = stopOnError;
+        this.verbosity = verbosity;
+    }
+
+    public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
+        this.delimiter = delimiter;
+        this.fullLineDelimiter = fullLineDelimiter;
+    }
+
+    /**
+     * Runs an SQL script (read in using the Reader parameter)
+     * 
+     * @param reader
+     *            - the source of the script
+     */
+    public void runScript(Reader reader) throws IOException, SQLException {
+        try {
+            boolean originalAutoCommit = connection.getAutoCommit();
+            try {
+                if (originalAutoCommit != this.autoCommit) {
+                    connection.setAutoCommit(this.autoCommit);
+                }
+                runScript(connection, reader);
+            } finally {
+                connection.setAutoCommit(originalAutoCommit);
+            }
+        } catch (IOException e) {
+            throw e;
+        } catch (SQLException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new RuntimeException("Error running script.  Cause: " + e, e);
+        }
+    }
+
+    /**
+     * Runs an SQL script (read in using the Reader parameter) using the
+     * connection passed in
+     * 
+     * @param conn
+     *            - the connection to use for the script
+     * @param reader
+     *            - the source of the script
+     * @throws SQLException
+     *             if any SQL errors occur
+     * @throws IOException
+     *             if there is an error reading from the Reader
+     */
+    private void runScript(Connection conn, Reader reader) throws IOException, SQLException {
+        StringBuffer command = null;
+        try {
+            LineNumberReader lineReader = new LineNumberReader(reader);
+            String line = null;
+            while ((line = lineReader.readLine()) != null) {
+                if (command == null) {
+                    command = new StringBuffer();
+                }
+                String trimmedLine = line.trim();
+                if (trimmedLine.startsWith("--")) {
+                    println(trimmedLine);
+                } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("//")) {
+                    // Do nothing
+                } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("--")) {
+                    // Do nothing
+                } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("#")) { 
+                    // Do nothing  
+                } else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter()) || fullLineDelimiter && trimmedLine.equals(getDelimiter())) {
+                    command.append(line.substring(0, line.lastIndexOf(getDelimiter())));
+                    command.append(" ");
+                    Statement statement = conn.createStatement();
+
+                    println(command);
+
+                    boolean hasResults = false;
+                    if (stopOnError) {
+                        hasResults = statement.execute(command.toString());
+                    } else {
+                        try {
+                            statement.execute(command.toString());
+                        } catch (SQLException e) {
+                            e.fillInStackTrace();
+                            printlnError("Error executing: " + command);
+                            printlnError(e);
+                        }
+                    }
+
+                    if (autoCommit && !conn.getAutoCommit()) {
+                        conn.commit();
+                    }
+
+                    ResultSet rs = statement.getResultSet();
+                    if (hasResults && rs != null) {
+                        ResultSetMetaData md = rs.getMetaData();
+                        int cols = md.getColumnCount();
+                        for (int i = 0; i < cols; i++) {
+                            String name = md.getColumnLabel(i);
+                            print(name + "\t");
+                        }
+                        println("");
+                        while (rs.next()) {
+                            for (int i = 0; i < cols; i++) {
+                                String value = rs.getString(i);
+                                print(value + "\t");
+                            }
+                            println("");
+                        }
+                    }
+
+                    command = null;
+                    try {
+                        statement.close();
+                    } catch (Exception e) {
+                        // Ignore to workaround a bug in Jakarta DBCP
+                    }
+                    Thread.yield();
+                } else {
+                    int idx = line.indexOf("--");
+                    if (idx != -1)
+                        command.append(line.substring(0, idx));
+                    else
+                        command.append(line);
+                    command.append(" ");
+                }
+            }
+            if (!autoCommit) {
+                conn.commit();
+            }
+        } catch (SQLException e) {
+            e.fillInStackTrace();
+            printlnError("Error executing: " + command);
+            printlnError(e);
+            throw e;
+        } catch (IOException e) {
+            e.fillInStackTrace();
+            printlnError("Error executing: " + command);
+            printlnError(e);
+            throw e;
+        } finally {
+            conn.rollback();
+            flush();
+        }
+    }
+
+    private String getDelimiter() {
+        return delimiter;
+    }
+
+    private void print(Object o) {
+        _logBuffer.append(o);
+    }
+
+    private void println(Object o) {
+        _logBuffer.append(o);
+        if (verbosity)
+            s_logger.debug(_logBuffer.toString());
+        _logBuffer = new StringBuffer();
+    }
+
+    private void printlnError(Object o) {
+        s_logger.error("" + o);
+    }
+
+    private void flush() {
+        if (_logBuffer.length() > 0) {
+            s_logger.debug(_logBuffer.toString());
+            _logBuffer = new StringBuffer();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/SearchBuilder.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SearchBuilder.java b/framework/db/src/com/cloud/utils/db/SearchBuilder.java
new file mode 100755
index 0000000..c177e20
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/SearchBuilder.java
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.util.Map;
+
+/**
+ * SearchBuilder is meant as a static query construct.  Often times in DAO code,
+ * we write static sql that just assumes the database table does not change.
+ * change by hand.  SearchBuilder is meant to replace that.  It provides load-time
+ * 
+ *   1. SearchBuilder is declared as final because it should not change after load time.
+ *   2. search.entity().getHostId() allows you to declare which field you are searching
+ *      on.  By doing this, we take advantage of the compiler to check that we
+ *      are not searching on obsolete fields.  You should try to use this
+ *      as much as possible as oppose to the addAndByField() and addOrByField() methods.
+ *   3. Note that the same SearchBuilder is used to create multiple SearchCriteria.
+ *      This is equivalent to clearing the parameters on PreparedStatement.  The
+ *      multiple SearchCriteria does not interfere with each other.
+ *   4. Note that the same field (getHostId()) was specified with two param
+ *      names.  This is basically allowing you to reuse the same field in two
+ *      parts of the search.
+ * 
+ * {@code
+ * final SearchBuilder<UserVmVO> search = _userVmDao.createSearchBuilder();
+ * final String param1 = "param1";
+ * final String param2 = "param2";
+ * search.addAnd(param1, search.entity().getHostId(), SearchCriteria.Op.NEQ);
+ * search.addAnd(param2, search.entity().getHostId(), SearchCriteria.op.GT);
+ * ...
+ * SearchCriteria sc = search.create();
+ * sc.setParameters(param1, 3);
+ * sc.setParameters(param2, 1);
+ * 
+ * ...
+ * 
+ * SearchCriteria sc2 = search.create();
+ * sc2.setParameters(param1, 4);
+ * sc2.setParameters(param2, 1);
+ * }
+ * 
+ * @param <T> VO object.
+ */
+public class SearchBuilder<T> extends GenericSearchBuilder<T, T> {
+    
+    @SuppressWarnings("unchecked")
+    public SearchBuilder(T entity, Map<String, Attribute> attrs) {
+        super(entity, (Class<T>)entity.getClass(), attrs);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/SearchCriteria.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SearchCriteria.java b/framework/db/src/com/cloud/utils/db/SearchCriteria.java
new file mode 100755
index 0000000..22bccd3
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/SearchCriteria.java
@@ -0,0 +1,364 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.GenericSearchBuilder.Condition;
+import com.cloud.utils.db.GenericSearchBuilder.Select;
+
+/**
+ * big joins or high performance searches, it is much better to
+ */
+public class SearchCriteria<K> {
+    public enum Op {
+        GT(" > ? ", 1),
+        GTEQ(" >= ? ", 1),
+        LT(" < ? ", 1),
+        LTEQ(" <= ? ", 1),
+        EQ(" = ? ", 1),
+        NEQ(" != ? ", 1),
+        BETWEEN(" BETWEEN ? AND ? ", 2),
+        NBETWEEN(" NOT BETWEEN ? AND ? ", 2),
+        IN(" IN () ", -1),
+        NOTIN(" NOT IN () ", -1),
+        LIKE(" LIKE ? ", 1),
+        NLIKE(" NOT LIKE ? ", 1),
+        NIN(" NOT IN () ", -1),
+        NULL(" IS NULL ", 0),
+        NNULL(" IS NOT NULL ", 0),
+        SC(" () ", 1),
+        TEXT("  () ", 1),
+        RP("", 0),
+        AND(" AND ", 0),
+        OR(" OR ", 0),
+        NOT(" NOT ", 0);
+
+        private final String op;
+        int params;
+        Op(String op, int params) {
+            this.op = op;
+            this.params = params;
+        }
+
+        @Override
+        public String toString() {
+            return op;
+        }
+
+        public int getParams() {
+            return params;
+        }
+    }
+
+    public enum Func {
+        NATIVE("@", 1),
+        MAX("MAX(@)", 1),
+        MIN("MIN(@)", 1),
+        FIRST("FIRST(@)", 1),
+        LAST("LAST(@)", 1),
+        SUM("SUM(@)", 1),
+        COUNT("COUNT(@)", 1),
+        DISTINCT("DISTINCT(@)", 1);
+
+        private String func;
+        private int count;
+
+        Func(String func, int params) {
+            this.func = func;
+            this.count = params;
+        }
+
+        @Override
+        public String toString() {
+            return func;
+        }
+
+        public int getCount() {
+            return count;
+        }
+    }
+
+    public enum SelectType {
+        Fields,
+        Entity,
+        Single,
+        Result
+    }
+
+    private final Map<String, Attribute> _attrs;
+    private final ArrayList<Condition> _conditions;
+    private ArrayList<Condition> _additionals = null;
+    private HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
+    private int _counter;
+    private HashMap<String, JoinBuilder<SearchCriteria<?>>> _joins;
+    private final ArrayList<Select> _selects;
+    private final GroupBy<?, K> _groupBy;
+    private final List<Object> _groupByValues;
+    private final Class<K> _resultType;
+    private final SelectType _selectType;
+
+    protected SearchCriteria(final Map<String, Attribute> attrs, ArrayList<GenericSearchBuilder.Condition> conditions, ArrayList<Select> selects, SelectType selectType, Class<K> resultType, HashMap<String, Object[]> params) {
+        this._attrs = attrs;
+        this._conditions = conditions;
+        this._selects = selects;
+        this._selectType = selectType;
+        this._resultType = resultType;
+        this._params = params;
+        this._additionals = new ArrayList<Condition>();
+        this._counter = 0;
+        this._joins = null;
+        this._groupBy = null;
+        this._groupByValues = null;
+    }
+
+    protected SearchCriteria(GenericSearchBuilder<?, K> sb) {
+        this._attrs = sb._attrs;
+        this._conditions = sb._conditions;
+        this._additionals = new ArrayList<Condition>();
+        this._counter = 0;
+        this._joins = null;
+        if (sb._joins != null) {
+            _joins = new HashMap<String, JoinBuilder<SearchCriteria<?>>>(sb._joins.size());
+            for (Map.Entry<String, JoinBuilder<GenericSearchBuilder<?, ?>>> entry : sb._joins.entrySet()) {
+                JoinBuilder<GenericSearchBuilder<?, ?>> value =  entry.getValue();
+                _joins.put(entry.getKey(), new JoinBuilder<SearchCriteria<?>>(value.getT().create(),value.getFirstAttribute(), value.getSecondAttribute(), value.getType()));
+            }
+        }
+        _selects = sb._selects;
+        _groupBy = sb._groupBy;
+        if (_groupBy != null) {
+            _groupByValues = new ArrayList<Object>();
+        } else {
+            _groupByValues = null;
+        }
+        _resultType = sb._resultType;
+        _selectType = sb._selectType;
+    }
+
+    public SelectType getSelectType() {
+        return _selectType;
+    }
+
+    public void getSelect(StringBuilder str, int insertAt) {
+        if (_selects == null || _selects.size() == 0) {
+            return;
+        }
+
+        for (Select select : _selects) {
+            String func = select.func.toString() + ",";
+            if (select.attr == null) {
+                func = func.replace("@", "*");
+            } else {
+                func = func.replace("@", select.attr.table + "." + select.attr.columnName);
+            }
+            str.insert(insertAt, func);
+            insertAt += func.length();
+            if (select.field == null) {
+                break;
+            }
+        }
+
+        str.delete(insertAt - 1, insertAt);
+    }
+
+    public List<Field> getSelectFields() {
+        List<Field> fields = new ArrayList<Field>(_selects.size());
+        for (Select select : _selects) {
+            fields.add(select.field);
+        }
+
+        return fields;
+    }
+
+    public void setParameters(String conditionName, Object... params) {
+        assert _conditions.contains(new Condition(conditionName)) || _additionals.contains(new Condition(conditionName)) : "Couldn't find " + conditionName;
+        _params.put(conditionName, params);
+    }
+
+    public boolean isSelectAll() {
+        return _selects == null || _selects.size() == 0;
+    }
+
+    protected JoinBuilder<SearchCriteria<?>> findJoin(Map<String, JoinBuilder<SearchCriteria<?>>> jbmap, String joinName) {
+    	JoinBuilder<SearchCriteria<?>> jb = jbmap.get(joinName);
+    	if (jb != null) {
+    		return jb;
+    	}
+    	
+    	for (JoinBuilder<SearchCriteria<?>> j2 : jbmap.values()) {
+    		SearchCriteria<?> sc = j2.getT();
+    		if(sc._joins != null)
+    		    jb = findJoin(sc._joins, joinName);
+    		if (jb != null) {
+    			return jb;
+    		}
+    	}
+    	
+    	assert (false) : "Unable to find a join by the name " + joinName;
+    	return null;
+    }
+
+    public void setJoinParameters(String joinName, String conditionName, Object... params) {
+        JoinBuilder<SearchCriteria<?>> join = findJoin(_joins, joinName);
+        assert (join != null) : "Incorrect join name specified: " + joinName;
+        join.getT().setParameters(conditionName, params);
+
+    }
+
+    public void addJoinAnd(String joinName, String field, Op op, Object... values) {
+        JoinBuilder<SearchCriteria<?>> join = _joins.get(joinName);
+        assert (join != null) : "Incorrect join name specified: " + joinName;
+        join.getT().addAnd(field, op, values);
+    }
+
+    public void addJoinOr(String joinName, String field, Op op, Object... values) {
+        JoinBuilder<SearchCriteria<?>> join = _joins.get(joinName);
+        assert (join != null) : "Incorrect join name specified: " + joinName;
+        join.getT().addOr(field, op, values);
+    }
+
+    public SearchCriteria<?> getJoin(String joinName) {
+        return _joins.get(joinName).getT();
+    }
+
+    public Pair<GroupBy<?, ?>, List<Object>> getGroupBy() {
+        return _groupBy == null ? null : new Pair<GroupBy<?, ?>, List<Object>>(_groupBy, _groupByValues);
+    }
+
+    public void setGroupByValues(Object... values) {
+        for (Object value : values) {
+            _groupByValues.add(value);
+        }
+    }
+
+    public Class<K> getResultType() {
+        return _resultType;
+    }
+
+    public void addAnd(String field, Op op, Object... values) {
+        String name = Integer.toString(_counter++);
+        addCondition(name, " AND ", field, op);
+        setParameters(name, values);
+    }
+
+    public void addAnd(Attribute attr, Op op, Object... values) {
+        String name = Integer.toString(_counter++);
+        addCondition(name, " AND ", attr, op);
+        setParameters(name, values);
+    }
+
+    public void addOr(String field, Op op, Object... values) {
+        String name = Integer.toString(_counter++);
+        addCondition(name, " OR ", field, op);
+        setParameters(name, values);
+    }
+
+    public void addOr(Attribute attr, Op op, Object... values) {
+        String name = Integer.toString(_counter++);
+        addCondition(name, " OR ", attr, op);
+        setParameters(name, values);
+    }
+
+    protected void addCondition(String conditionName, String cond, String fieldName, Op op) {
+        Attribute attr = _attrs.get(fieldName);
+        assert attr != null : "Unable to find field: " + fieldName;
+        addCondition(conditionName, cond, attr, op);
+    }
+
+    protected void addCondition(String conditionName, String cond, Attribute attr, Op op) {
+        Condition condition = new Condition(conditionName, /*(_conditions.size() + _additionals.size()) == 0 ? "" : */cond, attr, op);
+        _additionals.add(condition);
+    }
+
+    public String getWhereClause() {
+        StringBuilder sql = new StringBuilder();
+        int i = 0;
+        for (Condition condition : _conditions) {
+            if (condition.isPreset()) {
+                _params.put(condition.name, condition.presets);
+            }
+            Object[] params = _params.get(condition.name);
+            if ((condition.op == null || condition.op.params == 0) || (params != null)) {
+                condition.toSql(sql, params, i++);
+            }
+        }
+
+        for (Condition condition : _additionals) {
+            if (condition.isPreset()) {
+                _params.put(condition.name, condition.presets);
+            }
+            Object[] params = _params.get(condition.name);
+            if ((condition.op.params == 0) || (params != null)) {
+                condition.toSql(sql, params, i++);
+            }
+        }
+
+        return sql.toString();
+    }
+
+    public List<Pair<Attribute, Object>> getValues() {
+        ArrayList<Pair<Attribute, Object>> params = new ArrayList<Pair<Attribute, Object>>(_params.size());
+        for (Condition condition : _conditions) {
+            Object[] objs = _params.get(condition.name);
+            if (condition.op != null && condition.op.params != 0 && objs != null) {
+                getParams(params, condition, objs);
+            }
+        }
+
+        for (Condition condition : _additionals) {
+            Object[] objs = _params.get(condition.name);
+            if ((condition.op.params == 0) || (objs != null)) {
+                getParams(params, condition, objs);
+            }
+        }
+
+        return params;
+    }
+
+    public Collection<JoinBuilder<SearchCriteria<?>>> getJoins() {
+        return _joins != null ? _joins.values() : null;
+    }
+
+    private void getParams(ArrayList<Pair<Attribute, Object>> params, Condition condition, Object[] objs) {
+        if (condition.op == Op.SC) {
+            assert (objs != null && objs.length > 0) : " Where's your search criteria object? " + condition.name;
+            params.addAll(((SearchCriteria<?>)objs[0]).getValues());
+            return;
+        }
+
+        if (objs != null && objs.length > 0) {
+            for (Object obj : objs) {
+                if ((condition.op != Op.EQ && condition.op != Op.NEQ) || (obj != null)) {
+                    params.add(new Pair<Attribute, Object>(condition.attr, obj));
+                }
+            }
+        }
+    }
+
+    public Pair<String, ArrayList<Object>> toSql() {
+        StringBuilder sql = new StringBuilder();
+
+        return new Pair<String, ArrayList<Object>>(sql.toString(), null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/framework/db/src/com/cloud/utils/db/SearchCriteria2.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SearchCriteria2.java b/framework/db/src/com/cloud/utils/db/SearchCriteria2.java
new file mode 100755
index 0000000..67e95b0
--- /dev/null
+++ b/framework/db/src/com/cloud/utils/db/SearchCriteria2.java
@@ -0,0 +1,213 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.persistence.Transient;
+
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import com.cloud.utils.db.GenericSearchBuilder.Condition;
+import com.cloud.utils.db.GenericSearchBuilder.Select;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria.SelectType;
+
+public class SearchCriteria2<T, K> implements SearchCriteriaService<T, K>, MethodInterceptor{
+	GenericDao<? extends Serializable, ? extends Serializable> _dao;
+	final protected Map<String, Attribute> _attrs;
+	protected ArrayList<Attribute> _specifiedAttrs;
+	protected T _entity;
+	protected ArrayList<GenericSearchBuilder.Condition> _conditions;
+	protected ArrayList<Select> _selects;
+	private final HashMap<String, Object[]> _params = new HashMap<String, Object[]>();
+	protected Class<K> _resultType;
+    protected SelectType _selectType;
+    protected Class<T> _entityBeanType;
+	
+    protected SearchCriteria2(T entity, Class<K> resultType, final Map<String, Attribute> attrs, GenericDao<? extends Serializable, ? extends Serializable> dao) {
+		_entityBeanType = (Class<T>)entity.getClass();
+		_dao = dao;
+		_resultType = resultType;
+		_attrs = attrs;
+		_entity = entity;
+		_conditions = new ArrayList<Condition>();
+		_specifiedAttrs = new ArrayList<Attribute>();
+    }
+	
+	static public <T, K> SearchCriteria2<T, K> create(Class<T> entityType, Class<K> resultType) {
+		GenericDao<? extends Serializable, ? extends Serializable> dao = (GenericDao<? extends Serializable, ? extends Serializable>)GenericDaoBase.getDao(entityType);
+		assert dao != null : "Can not find DAO for " + entityType.getName();
+		SearchCriteria2<T, K> sc = dao.createSearchCriteria2(resultType);
+		return sc;
+	}
+	
+	static public <T, K> SearchCriteria2<T, K> create(Class<T> entityType) {
+		GenericDao<? extends Serializable, ? extends Serializable> dao = (GenericDao<? extends Serializable, ? extends Serializable>)GenericDaoBase.getDao(entityType);
+		assert dao != null : "Can not find DAO for " + entityType.getName();
+		SearchCriteria2<T, K> sc = dao.createSearchCriteria2();
+		return sc;
+	}
+	
+	@Override
+	public void selectField(Object... useless) {
+        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
+        assert _specifiedAttrs.size() > 0 : "You didn't specify any attributes";
+   
+        if (_selects == null) {
+            _selects = new ArrayList<Select>();
+        }
+        
+        for (Attribute attr : _specifiedAttrs) {
+            Field field = null;
+            try {
+                field = _resultType.getDeclaredField(attr.field.getName());
+                field.setAccessible(true);
+            } catch (SecurityException e) {
+            } catch (NoSuchFieldException e) {
+            }
+            _selects.add(new Select(Func.NATIVE, attr, field, null));
+        }
+        
+        _specifiedAttrs.clear();
+    }
+	
+    private void constructCondition(String conditionName, String cond, Attribute attr, Op op) {
+        assert _entity != null : "SearchBuilder cannot be modified once it has been setup";
+        assert op == null || _specifiedAttrs.size() == 1 : "You didn't select the attribute.";
+        assert op != Op.SC : "Call join";
+        
+        GenericSearchBuilder.Condition condition = new GenericSearchBuilder.Condition(conditionName, cond, attr, op);
+        _conditions.add(condition);
+        _specifiedAttrs.clear();
+    }
+    
+    private void setParameters(String conditionName, Object... params) {
+        assert _conditions.contains(new Condition(conditionName)) : "Couldn't find " + conditionName;
+        _params.put(conditionName, params);
+    }
+    
+	@Override
+	public void addAnd(Object useless, Op op, Object...values) {
+		String uuid = UUID.randomUUID().toString();
+		constructCondition(uuid, " AND ", _specifiedAttrs.get(0), op);
+		setParameters(uuid, values);
+	}
+	
+	@Override
+	public List<K> list() {
+		done();
+		SearchCriteria sc1 = createSearchCriteria();
+		if (isSelectAll()) {
+			return (List<K>)_dao.search(sc1, null);
+		} else {
+			return _dao.customSearch(sc1, null);
+		}
+	}
+	
+	private boolean isSelectAll() {
+        return _selects == null || _selects.size() == 0;
+    }
+	
+	@Override
+	public T getEntity() {
+		return _entity;
+	}
+
+	private SearchCriteria<K> createSearchCriteria() {
+		return new SearchCriteria<K>(_attrs, _conditions, _selects, _selectType, _resultType, _params);
+	}
+	
+    private void set(String name) {
+        Attribute attr = _attrs.get(name);
+        assert (attr != null) : "Searching for a field that's not there: " + name;
+        _specifiedAttrs.add(attr);
+    }
+    
+    private void done() {
+        if (_entity != null) {
+            Factory factory = (Factory)_entity;
+            factory.setCallback(0, null);
+            _entity = null;
+        }
+                
+        if (_selects == null || _selects.size() == 0) {
+            _selectType = SelectType.Entity;
+            assert _entityBeanType.equals(_resultType) : "Expecting " + _entityBeanType + " because you didn't specify any selects but instead got " + _resultType;
+            return;
+        }
+        
+        for (Select select : _selects) {
+            if (select.field == null) {
+                assert (_selects.size() == 1) : "You didn't specify any fields to put the result in but you're specifying more than one select so where should I put the selects?";
+                _selectType = SelectType.Single;
+                return;
+            }
+            if (select.func != null) {
+                _selectType = SelectType.Result;
+                return;
+            }
+        }
+        
+        _selectType = SelectType.Fields;
+    }
+    
+	@Override
+	public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
+		String name = method.getName();
+		if (method.getAnnotation(Transient.class) == null) {
+			if (name.startsWith("get")) {
+				String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+				set(fieldName);
+				return null;
+			} else if (name.startsWith("is")) {
+				String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
+				set(fieldName);
+				return null;
+			} else {
+				name = name.toLowerCase();
+				for (String fieldName : _attrs.keySet()) {
+					if (name.endsWith(fieldName.toLowerCase())) {
+						set(fieldName);
+						return null;
+					}
+				}
+				assert false : "Perhaps you need to make the method start with get or is?";
+			}
+		}
+        return methodProxy.invokeSuper(object, args);
+    }
+
+	@Override
+    public <K> K find() {
+		assert isSelectAll() : "find doesn't support select search";
+		done();
+		SearchCriteria sc1 = createSearchCriteria();
+		return (K)_dao.findOneBy(sc1);
+    }
+
+}


[04/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/GenericDaoBase.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java
deleted file mode 100755
index f593c38..0000000
--- a/utils/src/com/cloud/utils/db/GenericDaoBase.java
+++ /dev/null
@@ -1,1890 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.naming.ConfigurationException;
-import javax.persistence.AttributeOverride;
-import javax.persistence.Column;
-import javax.persistence.EmbeddedId;
-import javax.persistence.EntityExistsException;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
-import net.sf.cglib.proxy.NoOp;
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Element;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ComponentLifecycle;
-import com.cloud.utils.component.ComponentLifecycleBase;
-import com.cloud.utils.component.ComponentMethodInterceptable;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.db.SearchCriteria.SelectType;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-
-import edu.emory.mathcs.backport.java.util.Arrays;
-import edu.emory.mathcs.backport.java.util.Collections;
-
-/**
- *  GenericDaoBase is a simple way to implement DAOs.  It DOES NOT
- *  support the full EJB3 spec.  It borrows some of the annotations from
- *  the EJB3 spec to produce a set of SQLs so developers don't have to
- *  copy and paste the same code over and over again.  Of course,
- *  GenericDaoBase is completely at the mercy of the annotations you add
- *  to your entity bean.  If GenericDaoBase does not fit your needs, then
- *  don't extend from it.
- * 
- *  GenericDaoBase attempts to achieve the following:
- *    1. If you use _allFieldsStr in your SQL statement and use to() to convert
- *       the result to the entity bean, you don't ever have to worry about
- *       missing fields because its automatically taken from the entity bean's
- *       annotations.
- *    2. You don't have to rewrite the same insert and select query strings
- *       in all of your DAOs.
- *    3. You don't have to match the '?' (you know what I'm talking about) to
- *       the fields in the insert statement as that's taken care of for you.
- * 
- *  GenericDaoBase looks at the following annotations:
- *    1. Table - just name
- *    2. Column - just name
- *    3. GeneratedValue - any field with this annotation is not inserted.
- *    4. SequenceGenerator - sequence generator
- *    5. Id
- *    6. SecondaryTable
- * 
- *  Sometime later, I might look into injecting the SQLs as needed but right
- *  now we have to construct them at construction time.  The good thing is that
- *  the DAOs are suppose to be one per jvm so the time is all during the
- *  initial load.
- * 
- **/
-@DB
-public abstract class GenericDaoBase<T, ID extends Serializable> extends ComponentLifecycleBase implements GenericDao<T, ID>, ComponentMethodInterceptable {
-    private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class);
-
-    protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
-
-    protected final static Map<Class<?>, GenericDao<?, ? extends Serializable>> s_daoMaps = new ConcurrentHashMap<Class<?>, GenericDao<?, ? extends Serializable>>(71);
-
-    protected Class<T> _entityBeanType;
-    protected String _table;
-
-    protected String _tables;
-
-    protected Field[] _embeddedFields;
-
-    // This is private on purpose.  Everyone should use createPartialSelectSql()
-    private final Pair<StringBuilder, Attribute[]> _partialSelectSql;
-    private final Pair<StringBuilder, Attribute[]> _partialQueryCacheSelectSql;
-    protected StringBuilder _discriminatorClause;
-    protected Map<String, Object> _discriminatorValues;
-    protected String _selectByIdSql;
-    protected String _count;
-
-    protected Field _idField;
-
-    protected List<Pair<String, Attribute[]>> _insertSqls;
-    protected Pair<String, Attribute> _removed;
-    protected Pair<String, Attribute[]> _removeSql;
-    protected List<Pair<String, Attribute[]>> _deleteSqls;
-    protected Map<String, Attribute[]> _idAttributes;
-    protected Map<String, TableGenerator> _tgs;
-    protected Map<String, Attribute> _allAttributes;
-    protected List<Attribute> _ecAttributes;
-    protected Map<Pair<String, String>, Attribute> _allColumns;
-    protected Enhancer _enhancer;
-    protected Factory _factory;
-    protected Enhancer _searchEnhancer;
-    protected int _timeoutSeconds;
-
-    protected final static CallbackFilter s_callbackFilter = new UpdateFilter();
-
-    protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE ";
-    protected static final String SHARE_MODE_CLAUSE = " LOCK IN SHARE MODE";
-    protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()";
-
-    protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance();
-
-    public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
-        @SuppressWarnings("unchecked")
-        GenericDao<? extends J, ? extends Serializable> dao = (GenericDao<? extends J, ? extends Serializable>)s_daoMaps.get(entityType);
-        assert dao != null : "Unable to find DAO for " + entityType + ".  Are you sure you waited for the DAO to be initialized before asking for it?";
-        return dao;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked") @DB(txn=false)
-    public <J> GenericSearchBuilder<T, J> createSearchBuilder(Class<J> resultType) {
-        final T entity = (T)_searchEnhancer.create();
-        final Factory factory = (Factory)entity;
-        GenericSearchBuilder<T, J> builder = new GenericSearchBuilder<T, J>(entity, resultType, _allAttributes);
-        factory.setCallback(0, builder);
-        return builder;
-    }
-
-    @Override
-    public Map<String, Attribute> getAllAttributes() {
-        return _allAttributes;
-    }
-    
-    @SuppressWarnings("unchecked")
-    protected GenericDaoBase() {
-        Type t = getClass().getGenericSuperclass();
-        if (t instanceof ParameterizedType) {
-            _entityBeanType = (Class<T>)((ParameterizedType)t).getActualTypeArguments()[0];
-        } else if (((Class<?>)t).getGenericSuperclass() instanceof ParameterizedType) {
-            _entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)t).getGenericSuperclass()).getActualTypeArguments()[0];
-        } else {
-            _entityBeanType = (Class<T>)((ParameterizedType)
-                    ( (Class<?>)((Class<?>)t).getGenericSuperclass()).getGenericSuperclass()).getActualTypeArguments()[0];
-        }
-
-        s_daoMaps.put(_entityBeanType, this);
-        Class<?>[] interphaces = _entityBeanType.getInterfaces();
-        if (interphaces != null) {
-            for (Class<?> interphace : interphaces) {
-                s_daoMaps.put(interphace, this);
-            }
-        }
-  
-        _table = DbUtil.getTableName(_entityBeanType);
-
-        final SqlGenerator generator = new SqlGenerator(_entityBeanType);
-        _partialSelectSql = generator.buildSelectSql(false);
-        _count = generator.buildCountSql();
-        _partialQueryCacheSelectSql = generator.buildSelectSql(true);
-        _embeddedFields = generator.getEmbeddedFields();
-        _insertSqls = generator.buildInsertSqls();
-        final Pair<StringBuilder, Map<String, Object>> dc = generator.buildDiscriminatorClause();
-        _discriminatorClause = dc.first().length() == 0 ? null : dc.first();
-        _discriminatorValues = dc.second();
-
-        _idAttributes = generator.getIdAttributes();
-        _idField = _idAttributes.get(_table).length > 0 ? _idAttributes.get(_table)[0].field : null;
-
-        _tables = generator.buildTableReferences();
-
-        _allAttributes = generator.getAllAttributes();
-        _allColumns = generator.getAllColumns();
-
-        _selectByIdSql = buildSelectByIdSql(createPartialSelectSql(null, true));
-        _removeSql = generator.buildRemoveSql();
-        _deleteSqls = generator.buildDeleteSqls();
-        _removed = generator.getRemovedAttribute();
-        _tgs = generator.getTableGenerators();
-        _ecAttributes = generator.getElementCollectionAttributes();
-
-        TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class);
-        if (tg != null) {
-            _tgs.put(tg.name(), tg);
-        }
-        tg = this.getClass().getSuperclass().getAnnotation(TableGenerator.class);
-        if (tg != null) {
-            _tgs.put(tg.name(), tg);
-        }
-
-        Callback[] callbacks = new Callback[] { NoOp.INSTANCE, new UpdateBuilder(this) };
-
-        _enhancer = new Enhancer();
-        _enhancer.setSuperclass(_entityBeanType);
-        _enhancer.setCallbackFilter(s_callbackFilter);
-        _enhancer.setCallbacks(callbacks);
-        _factory = (Factory)_enhancer.create();
-
-        _searchEnhancer = new Enhancer();
-        _searchEnhancer.setSuperclass(_entityBeanType);
-        _searchEnhancer.setCallback(new UpdateBuilder(this));
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Select SQL: " + _partialSelectSql.first().toString());
-            s_logger.trace("Remove SQL: " + (_removeSql != null ? _removeSql.first() : "No remove sql"));
-            s_logger.trace("Select by Id SQL: " + _selectByIdSql);
-            s_logger.trace("Table References: " + _tables);
-            s_logger.trace("Insert SQLs:");
-            for (final Pair<String, Attribute[]> insertSql : _insertSqls) {
-                s_logger.trace(insertSql.first());
-            }
-
-            s_logger.trace("Delete SQLs");
-            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
-                s_logger.trace(deletSql.first());
-            }
-
-            s_logger.trace("Collection SQLs");
-            for (Attribute attr : _ecAttributes) {
-                EcInfo info = (EcInfo)attr.attache;
-                s_logger.trace(info.insertSql);
-                s_logger.trace(info.selectSql);
-            }
-        }
-        
-        setRunLevel(ComponentLifecycle.RUN_LEVEL_SYSTEM);
-    }
-
-    @Override @DB(txn=false)
-    @SuppressWarnings("unchecked")
-    public T createForUpdate(final ID id) {
-        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
-        if (id != null) {
-            try {
-                _idField.set(entity, id);
-            } catch (final IllegalArgumentException e) {
-            } catch (final IllegalAccessException e) {
-            }
-        }
-        return entity;
-    }
-
-    @Override @DB(txn=false)
-    public T createForUpdate() {
-        return createForUpdate(null);
-    }
-
-    @Override @DB(txn=false)
-    public <K> K getNextInSequence(final Class<K> clazz, final String name) {
-        final TableGenerator tg = _tgs.get(name);
-        assert (tg != null) : "Couldn't find Table generator using " + name;
-
-        return s_seqFetcher.getNextSequence(clazz, tg);
-    }
-
-    @Override @DB(txn=false)
-    public <K> K getRandomlyIncreasingNextInSequence(final Class<K> clazz, final String name) {
-        final TableGenerator tg = _tgs.get(name);
-        assert (tg != null) : "Couldn't find Table generator using " + name;
-
-        return s_seqFetcher.getRandomNextSequence(clazz, tg);
-    }
-
-    @Override @DB(txn=false)
-    public List<T> lockRows(final SearchCriteria<T> sc, final Filter filter, final boolean exclusive) {
-        return search(sc, filter, exclusive, false);
-    }
-
-    @Override @DB(txn=false)
-    public T lockOneRandomRow(final SearchCriteria<T> sc, final boolean exclusive) {
-        final Filter filter = new Filter(1);
-        final List<T> beans = search(sc, filter, exclusive, true);
-        return beans.isEmpty() ? null : beans.get(0);
-    }
-
-    @DB(txn=false)
-    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
-        if (_removed != null) {
-            if (sc == null) {
-                sc = createSearchCriteria();
-            }
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return searchIncludingRemoved(sc, filter, lock, cache);
-    }
-
-    @DB(txn=false)
-    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enable_query_cache) {
-        if (_removed != null) {
-            if (sc == null) {
-                sc = createSearchCriteria();
-            }
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return searchIncludingRemoved(sc, filter, lock, cache, enable_query_cache);
-    }
-
-    @Override
-    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
-        return searchIncludingRemoved(sc, filter, lock, cache, false) ;
-    }
-
-    @Override
-    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock,
-            final boolean cache, final boolean enable_query_cache) {
-        String clause = sc != null ? sc.getWhereClause() : null;
-        if (clause != null && clause.length() == 0) {
-            clause = null;
-        }
-
-        final StringBuilder str = createPartialSelectSql(sc, clause != null, enable_query_cache);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        if (sc != null) {
-            joins = sc.getJoins();
-            if (joins != null) {
-                addJoins(str, joins);
-            }
-        }
-
-        List<Object> groupByValues = addGroupBy(str, sc);
-        addFilter(str, filter);
-
-        final Transaction txn = Transaction.currentTxn();
-        if (lock != null) {
-            assert (txn.dbTxnStarted() == true) : "As nice as I can here now....how do you lock when there's no DB transaction?  Review your db 101 course from college.";
-            str.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
-        }
-
-        final String sql = str.toString();
-
-        PreparedStatement pstmt = null;
-        final List<T> result = new ArrayList<T>();
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 0;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(++i, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            if (groupByValues != null) {
-                for (Object value : groupByValues) {
-                    pstmt.setObject(i++, value);
-                }
-            }
-
-            if (s_logger.isDebugEnabled() && lock != null) {
-                txn.registerLock(pstmt.toString());
-            }
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                result.add(toEntityBean(rs, cache));
-            }
-            return result;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @Override @SuppressWarnings("unchecked")
-    public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, final Filter filter) {
-        if (sc.isSelectAll()) {
-            return (List<M>)searchIncludingRemoved((SearchCriteria<T>)sc, filter, null, false);
-        }
-        String clause = sc != null ? sc.getWhereClause() : null;
-        if (clause != null && clause.length() == 0) {
-            clause = null;
-        }
-
-        final StringBuilder str = createPartialSelectSql(sc, clause != null);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        if (sc != null) {
-            joins = sc.getJoins();
-            if (joins != null) {
-                addJoins(str, joins);
-            }
-        }
-
-        List<Object> groupByValues = addGroupBy(str, sc);
-        addFilter(str, filter);
-
-        final String sql = str.toString();
-
-        final Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 0;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(++i, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            if (groupByValues != null) {
-                for (Object value : groupByValues) {
-                    pstmt.setObject(i++, value);
-                }
-            }
-
-            ResultSet rs = pstmt.executeQuery();
-            SelectType st = sc.getSelectType();
-            ArrayList<M> results = new ArrayList<M>();
-            List<Field> fields = sc.getSelectFields();
-            while (rs.next()) {
-                if (st == SelectType.Entity) {
-                    results.add((M)toEntityBean(rs, false));
-                } else if (st == SelectType.Fields || st == SelectType.Result) {
-                    M m = sc.getResultType().newInstance();
-                    for (int j = 1; j <= fields.size(); j++) {
-                        setField(m, fields.get(j - 1), rs, j);
-                    }
-                    results.add(m);
-                } else if (st == SelectType.Single) {
-                    results.add(getObject(sc.getResultType(), rs, 1));
-                }
-            }
-
-            return results;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @Override @DB(txn=false)
-    public <M> List<M> customSearch(SearchCriteria<M> sc, final Filter filter) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-
-        return customSearchIncludingRemoved(sc, filter);
-    }
-
-    @DB(txn=false)
-    protected void setField(Object entity, Field field, ResultSet rs, int index) throws SQLException {
-        try {
-            final Class<?> type = field.getType();
-            if (type == String.class) {
-                byte[] bytes = rs.getBytes(index);
-                if(bytes != null) {
-                    try {
-                        Encrypt encrypt = field.getAnnotation(Encrypt.class);
-                        if (encrypt != null && encrypt.encrypt()){
-                            field.set(entity, DBEncryptionUtil.decrypt(new String(bytes, "UTF-8")));
-                        } else {
-                            field.set(entity, new String(bytes, "UTF-8"));
-                        }
-                    } catch (IllegalArgumentException e) {
-                        assert(false);
-                        throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data");
-                    } catch (UnsupportedEncodingException e) {
-                        assert(false);
-                        throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data");
-                    }
-                } else {
-                    field.set(entity, null);
-                }
-            } else if (type == long.class) {
-                field.setLong(entity, rs.getLong(index));
-            } else if (type == Long.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getLong(index));
-                }
-            } else if (type.isEnum()) {
-                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
-                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
-
-                final Enum<?>[] enums =  (Enum<?>[])field.getType().getEnumConstants();
-                for (final Enum<?> e : enums) {
-                    if ((enumType == EnumType.STRING && e.name().equalsIgnoreCase(rs.getString(index))) ||
-                            (enumType == EnumType.ORDINAL && e.ordinal() == rs.getInt(index))) {
-                        field.set(entity, e);
-                        return;
-                    }
-                }
-            } else if (type == int.class) {
-                field.set(entity, rs.getInt(index));
-            } else if (type == Integer.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getInt(index));
-                }
-            } else if (type == Date.class) {
-                final Object data = rs.getDate(index);
-                if (data == null) {
-                    field.set(entity, null);
-                    return;
-                }
-                field.set(entity, DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
-            } else if (type == Calendar.class) {
-                final Object data = rs.getDate(index);
-                if (data == null) {
-                    field.set(entity, null);
-                    return;
-                }
-                final Calendar cal = Calendar.getInstance();
-                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
-                field.set(entity, cal);
-            } else if (type == boolean.class) {
-                field.setBoolean(entity, rs.getBoolean(index));
-            } else if (type == Boolean.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getBoolean(index));
-                }
-            } else if (type == URI.class) {
-                try {
-                    String str = rs.getString(index);
-                    field.set(entity, str == null ? null : new URI(str));
-                } catch (URISyntaxException e) {
-                    throw new CloudRuntimeException("Invalid URI: " + rs.getString(index), e);
-                }
-            } else if (type == URL.class) {
-                try {
-                    String str = rs.getString(index);
-                    field.set(entity, str != null ? new URL(str) : null);
-                } catch (MalformedURLException e) {
-                    throw new CloudRuntimeException("Invalid URL: " + rs.getString(index), e);
-                }
-            } else if (type == Ip.class) {
-                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
-                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
-
-                Ip ip = null;
-                if (enumType == EnumType.STRING) {
-                    String s = rs.getString(index);
-                    ip = s == null ? null : new Ip(NetUtils.ip2Long(s));
-                } else {
-                    ip = new Ip(rs.getLong(index));
-                }
-                field.set(entity, ip);
-            } else if (type == short.class) {
-                field.setShort(entity, rs.getShort(index));
-            } else if (type == Short.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getShort(index));
-                }
-            } else if (type == float.class) {
-                field.setFloat(entity, rs.getFloat(index));
-            } else if (type == Float.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getFloat(index));
-                }
-            } else if (type == double.class) {
-                field.setDouble(entity, rs.getDouble(index));
-            } else if (type == Double.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getDouble(index));
-                }
-            } else if (type == byte.class) {
-                field.setByte(entity, rs.getByte(index));
-            } else if (type == Byte.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getByte(index));
-                }
-            } else if (type == byte[].class) {
-                field.set(entity, rs.getBytes(index));
-            } else {
-                field.set(entity, rs.getObject(index));
-            }
-        } catch (final IllegalAccessException e) {
-            throw new CloudRuntimeException("Yikes! ", e);
-        }
-    }
-
-    @DB(txn=false) @SuppressWarnings("unchecked")
-    protected <M> M getObject(Class<M> type, ResultSet rs, int index) throws SQLException {
-        if (type == String.class) {
-            byte[] bytes = rs.getBytes(index);
-            if(bytes != null) {
-                try {
-                    return (M)new String(bytes, "UTF-8");
-                } catch (UnsupportedEncodingException e) {
-                    throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data");
-                }
-            } else {
-                return null;
-            }
-        } else if (type == int.class) {
-            return (M)new Integer(rs.getInt(index));
-        } else if (type == Integer.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M)new Integer(rs.getInt(index));
-            }
-        } else if (type == long.class) {
-            return (M)new Long(rs.getLong(index));
-        } else if (type == Long.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M)new Long(rs.getLong(index));
-            }
-        } else if (type == Date.class) {
-            final Object data = rs.getDate(index);
-            if (data == null) {
-                return null;
-            } else {
-                return (M)DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index));
-            }
-        } else if (type == short.class) {
-            return (M)new Short(rs.getShort(index));
-        } else if (type == Short.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M)new Short(rs.getShort(index));
-            }
-        } else if (type == boolean.class) {
-            return (M)new Boolean(rs.getBoolean(index));
-        } else if (type == Boolean.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M)new Boolean(rs.getBoolean(index));
-            }
-        } else if (type == float.class) {
-            return (M)new Float(rs.getFloat(index));
-        } else if (type == Float.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M)new Float(rs.getFloat(index));
-            }
-        } else if (type == double.class) {
-            return (M)new Double(rs.getDouble(index));
-        } else if (type == Double.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M)new Double(rs.getDouble(index));
-            }
-        } else if (type == byte.class) {
-            return (M)new Byte(rs.getByte(index));
-        } else if (type == Byte.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M)new Byte(rs.getByte(index));
-            }
-        } else if (type == Calendar.class) {
-            final Object data = rs.getDate(index);
-            if (data == null) {
-                return null;
-            } else {
-                final Calendar cal = Calendar.getInstance();
-                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
-                return (M)cal;
-            }
-        } else if (type == byte[].class) {
-            return (M)rs.getBytes(index);
-        } else {
-            return (M)rs.getObject(index);
-        }
-    }
-
-    @DB(txn=false)
-    protected int addJoinAttributes(int count, PreparedStatement pstmt, Collection<JoinBuilder<SearchCriteria<?>>> joins) throws SQLException {
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            for (final Pair<Attribute, Object> value : join.getT().getValues()) {
-                prepareAttribute(++count, pstmt, value.first(), value.second());
-            }
-        }
-
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            if (join.getT().getJoins() != null) {
-                count = addJoinAttributes(count, pstmt, join.getT().getJoins());
-            }
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("join search statement is " + pstmt);
-        }
-        return count;
-    }
-
-    protected int update(ID id, UpdateBuilder ub, T entity) {
-        if (_cache != null) {
-            _cache.remove(id);
-        }
-        SearchCriteria<T> sc = createSearchCriteria();
-        sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        try {
-            if (ub.getCollectionChanges() != null) {
-                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ub.getCollectionChanges());
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to persist element collection", e);
-        }
-
-        int rowsUpdated = update(ub, sc, null);
-
-        txn.commit();
-
-        return rowsUpdated;
-    }
-
-    public int update(UpdateBuilder ub, final SearchCriteria<?> sc, Integer rows) {
-        StringBuilder sql = null;
-        PreparedStatement pstmt = null;
-        final Transaction txn = Transaction.currentTxn();
-        try {
-            final String searchClause = sc.getWhereClause();
-
-            sql = ub.toSql(_tables);
-            if (sql == null) {
-                return  0;
-            }
-
-            sql.append(searchClause);
-
-            if (rows != null) {
-                sql.append(" LIMIT ").append(rows);
-            }
-
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(sql.toString());
-
-            Collection<Ternary<Attribute, Boolean, Object>> changes = ub.getChanges();
-
-            int i = 1;
-            for (final Ternary<Attribute, Boolean, Object> value : changes) {
-                prepareAttribute(i++, pstmt, value.first(), value.third());
-            }
-
-            for (Pair<Attribute, Object> value : sc.getValues()) {
-                prepareAttribute(i++, pstmt, value.first(), value.second());
-            }
-
-            int result = pstmt.executeUpdate();
-            txn.commit();
-            ub.clear();
-            return result;
-        } catch (final SQLException e) {
-            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
-                throw new EntityExistsException("Entity already exists ", e);
-            }
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    @DB(txn=false)
-    protected Attribute findAttributeByFieldName(String name) {
-        return _allAttributes.get(name);
-    }
-
-    @DB(txn=false)
-    protected String buildSelectByIdSql(final StringBuilder sql) {
-        if (_idField == null) {
-            return null;
-        }
-
-        if (_idField.getAnnotation(EmbeddedId.class) == null) {
-            sql.append(_table).append(".").append(DbUtil.getColumnName(_idField, null)).append(" = ? ");
-        } else {
-            final Class<?> clazz = _idField.getClass();
-            final AttributeOverride[] overrides = DbUtil.getAttributeOverrides(_idField);
-            for (final Field field : clazz.getDeclaredFields()) {
-                sql.append(_table).append(".").append(DbUtil.getColumnName(field, overrides)).append(" = ? AND ");
-            }
-            sql.delete(sql.length() - 4, sql.length());
-        }
-
-        return sql.toString();
-    }
-
-    @DB(txn=false)
-    @Override
-    public Class<T> getEntityBeanType() {
-        return _entityBeanType;
-    }
-
-    @DB(txn=false)
-    protected T findOneIncludingRemovedBy(final SearchCriteria<T> sc) {
-        Filter filter = new Filter(1);
-        List<T> results = searchIncludingRemoved(sc, filter, null, false);
-        assert results.size() <= 1 : "Didn't the limiting worked?";
-        return results.size() == 0 ? null : results.get(0);
-    }
-
-    @Override
-    @DB(txn=false)
-    public T findOneBy(final SearchCriteria<T> sc) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @DB(txn=false)
-    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return listIncludingRemovedBy(sc, filter);
-    }
-
-    @DB(txn=false)
-    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter, final boolean enable_query_cache) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return listIncludingRemovedBy(sc, filter, enable_query_cache);
-    }
-
-    @DB(txn=false)
-    protected List<T> listBy(final SearchCriteria<T> sc) {
-        return listBy(sc, null);
-    }
-
-    @DB(txn=false)
-    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter, final boolean enable_query_cache) {
-        return searchIncludingRemoved(sc, filter, null, false, enable_query_cache);
-    }
-
-    @DB(txn=false)
-    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter) {
-        return searchIncludingRemoved(sc, filter, null, false);
-    }
-
-    @DB(txn=false)
-    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc) {
-        return listIncludingRemovedBy(sc, null);
-    }
-
-    @Override @DB(txn=false)
-    @SuppressWarnings("unchecked")
-    public T findById(final ID id) {
-        if (_cache != null) {
-            final Element element = _cache.get(id);
-            return element == null ? lockRow(id, null) : (T)element.getObjectValue();
-        } else {
-            return lockRow(id, null);
-        }
-    }
-
-    @Override @DB(txn=false)
-    @SuppressWarnings("unchecked")
-    public T findByUuid(final String uuid) {
-        SearchCriteria<T> sc = createSearchCriteria();
-        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
-        return findOneBy(sc);
-    }
-
-    @Override @DB(txn=false)
-    @SuppressWarnings("unchecked")
-    public T findByUuidIncludingRemoved(final String uuid) {
-        SearchCriteria<T> sc = createSearchCriteria();
-        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override @DB(txn=false)
-    public T findByIdIncludingRemoved(ID id) {
-        return findById(id, true, null);
-    }
-
-    @Override @DB(txn=false)
-    public T findById(final ID id, boolean fresh) {
-        if(!fresh) {
-            return findById(id);
-        }
-
-        if (_cache != null) {
-            _cache.remove(id);
-        }
-        return lockRow(id, null);
-    }
-
-    @Override @DB(txn=false)
-    public T lockRow(ID id, Boolean lock) {
-        return findById(id, false, lock);
-    }
-
-    protected T findById(ID id, boolean removed, Boolean lock) {
-        StringBuilder sql = new StringBuilder(_selectByIdSql);
-        if (!removed && _removed != null) {
-            sql.append(" AND ").append(_removed.first());
-        }
-        if (lock != null) {
-            sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
-        }
-        Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql.toString());
-
-            if (_idField.getAnnotation(EmbeddedId.class) == null) {
-                prepareAttribute(1, pstmt, _idAttributes.get(_table)[0], id);
-            }
-
-            ResultSet rs = pstmt.executeQuery();
-            return rs.next() ? toEntityBean(rs, true) : null;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    @Override @DB(txn=false)
-    public T acquireInLockTable(ID id) {
-        return acquireInLockTable(id, _timeoutSeconds);
-    }
-
-    @Override
-    public T acquireInLockTable(final ID id, int seconds) {
-        Transaction txn = Transaction.currentTxn();
-        T t = null;
-        boolean locked  = false;
-        try {
-            if (!txn.lock(_table + id.toString(), seconds)) {
-                return null;
-            }
-
-            locked = true;
-            t = findById(id);
-            return t;
-        } finally {
-            if (t == null && locked) {
-                txn.release(_table + id.toString());
-            }
-        }
-    }
-
-    @Override
-    public boolean releaseFromLockTable(final ID id) {
-        final Transaction txn = Transaction.currentTxn();
-        return txn.release(_table + id);
-    }
-
-    @Override @DB(txn=false)
-    public boolean lockInLockTable(final String id) {
-        return lockInLockTable(id, _timeoutSeconds);
-    }
-
-    @Override
-    public boolean lockInLockTable(final String id, int seconds) {
-        Transaction txn = Transaction.currentTxn();
-        return txn.lock(_table + id, seconds);
-    }
-
-    @Override
-    public boolean unlockFromLockTable(final String id) {
-        final Transaction txn = Transaction.currentTxn();
-        return txn.release(_table + id);
-    }
-
-    @Override @DB(txn=false)
-    public List<T> listAllIncludingRemoved() {
-        return listAllIncludingRemoved(null);
-    }
-
-    @DB(txn=false)
-    protected List<Object> addGroupBy(final StringBuilder sql, SearchCriteria<?> sc) {
-        Pair<GroupBy<?, ?>, List<Object>> groupBys = sc.getGroupBy();
-        if (groupBys != null) {
-            groupBys.first().toSql(sql);
-            return groupBys.second();
-        } else {
-            return null;
-        }
-    }
-
-    @DB(txn=false)
-    protected void addFilter(final StringBuilder sql, final Filter filter) {
-        if (filter != null) {
-            if (filter.getOrderBy() != null) {
-                sql.append(filter.getOrderBy());
-            }
-            if (filter.getOffset() != null) {
-                sql.append(" LIMIT ");
-                sql.append(filter.getOffset());
-                if (filter.getLimit() != null) {
-                    sql.append(", ").append(filter.getLimit());
-                }
-            }
-        }
-    }
-
-    @Override @DB(txn=false)
-    public List<T> listAllIncludingRemoved(final Filter filter) {
-        final StringBuilder sql = createPartialSelectSql(null, false);
-        addFilter(sql, filter);
-
-        return executeList(sql.toString());
-    }
-
-    protected List<T> executeList(final String sql, final Object... params) {
-        final Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        final List<T> result = new ArrayList<T>();
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 0;
-            for (final Object param : params) {
-                pstmt.setObject(++i, param);
-            }
-
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                result.add(toEntityBean(rs, true));
-            }
-            return result;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @Override @DB(txn=false)
-    public List<T> listAll() {
-        return listAll(null);
-    }
-
-    @Override @DB(txn=false)
-    public List<T> listAll(final Filter filter) {
-        if (_removed == null) {
-            return listAllIncludingRemoved(filter);
-        }
-
-        final StringBuilder sql = createPartialSelectSql(null, true);
-        sql.append(_removed.first());
-        addFilter(sql, filter);
-
-        return executeList(sql.toString());
-    }
-
-    @Override
-    public boolean expunge(final ID id) {
-        final Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = null;
-        try {
-            txn.start();
-            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
-                sql = deletSql.first();
-                final Attribute[] attrs = deletSql.second();
-
-                pstmt = txn.prepareAutoCloseStatement(sql);
-
-                for (int i = 0; i < attrs.length; i++) {
-                    prepareAttribute(i + 1, pstmt, attrs[i], id);
-                }
-                pstmt.executeUpdate();
-            }
-
-            txn.commit();
-            if (_cache != null) {
-                _cache.remove(id);
-            }
-            return true;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    // FIXME: Does not work for joins.
-    @Override
-    public int expunge(final SearchCriteria<T> sc) {
-        final StringBuilder str = new StringBuilder("DELETE FROM ");
-        str.append(_table);
-        str.append(" WHERE ");
-
-        if (sc != null && sc.getWhereClause().length() > 0) {
-            str.append(sc.getWhereClause());
-        }
-
-        final String sql = str.toString();
-
-        final Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 0;
-            for (final Pair<Attribute, Object> value : sc.getValues()) {
-                prepareAttribute(++i, pstmt, value.first(), value.second());
-            }
-            return pstmt.executeUpdate();
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @DB(txn=false)
-    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause, final boolean enable_query_cache) {
-        StringBuilder sql = new StringBuilder(enable_query_cache ? _partialQueryCacheSelectSql.first() : _partialSelectSql.first());
-        if (sc != null && !sc.isSelectAll()) {
-            sql.delete(7, sql.indexOf(" FROM"));
-            sc.getSelect(sql, 7);
-        }
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-
-    @DB(txn=false)
-    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause) {
-        StringBuilder sql = new StringBuilder(_partialSelectSql.first());
-        if (sc != null && !sc.isSelectAll()) {
-            sql.delete(7, sql.indexOf(" FROM"));
-            sc.getSelect(sql, 7);
-        }
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-
-
-    @DB(txn = false)
-    protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
-        int fromIndex = str.lastIndexOf("WHERE");
-        if (fromIndex == -1) {
-            fromIndex = str.length();
-            str.append(" WHERE ");
-        } else {
-            str.append(" AND ");
-        }
-
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            StringBuilder onClause = new StringBuilder();
-            onClause.append(" ").append(join.getType().getName()).append(" ").append(join.getSecondAttribute().table)
-            .append(" ON ").append(join.getFirstAttribute().table).append(".").append(join.getFirstAttribute().columnName)
-            .append("=").append(join.getSecondAttribute().table).append(".").append(join.getSecondAttribute().columnName)
-            .append(" ");
-            str.insert(fromIndex, onClause);
-            String whereClause = join.getT().getWhereClause();
-            if ((whereClause != null) && !"".equals(whereClause)) {
-                str.append(" (").append(whereClause).append(") AND");
-            }
-            fromIndex += onClause.length();
-        }
-
-        str.delete(str.length() - 4, str.length());
-
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            if (join.getT().getJoins() != null) {
-                addJoins(str, join.getT().getJoins());
-            }
-        }
-    }
-
-    @Override @DB(txn=false)
-    public List<T> search(final SearchCriteria<T> sc, final Filter filter) {
-        return search(sc, filter, null, false);
-    }
-
-    @Override @DB(txn=false)
-    public Pair<List<T>, Integer> searchAndCount(final SearchCriteria<T> sc, final Filter filter) {
-        List<T> objects = search(sc, filter, null, false);
-        Integer count = getCount(sc);
-        return new Pair<List<T>, Integer>(objects, count);
-    }
-
-    @Override @DB(txn=false)
-    public List<T> search(final SearchCriteria<T> sc, final Filter filter, final boolean enable_query_cache) {
-        return search(sc, filter, null, false, enable_query_cache);
-    }
-
-    @Override @DB(txn=false)
-    public boolean update(ID id, T entity) {
-        assert Enhancer.isEnhanced(entity.getClass()) : "Entity is not generated by this dao";
-
-        UpdateBuilder ub = getUpdateBuilder(entity);
-        boolean result = update(id, ub, entity) != 0;
-        return result;
-    }
-
-    @DB(txn=false)
-    public int update(final T entity, final SearchCriteria<T> sc, Integer rows) {
-        final UpdateBuilder ub = getUpdateBuilder(entity);
-        return update(ub, sc, rows);
-    }
-
-    @DB(txn=false)
-    public int update(final T entity, final SearchCriteria<T> sc) {
-        final UpdateBuilder ub = getUpdateBuilder(entity);
-        return update(ub, sc, null);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T persist(final T entity) {
-        if (Enhancer.isEnhanced(entity.getClass())) {
-            if (_idField != null) {
-                ID id;
-                try {
-                    id = (ID)_idField.get(entity);
-                } catch (IllegalAccessException e) {
-                    throw new CloudRuntimeException("How can it be illegal access...come on", e);
-                }
-                update(id, entity);
-                return entity;
-            }
-
-            assert false : "Can't call persit if you don't have primary key";
-        }
-
-        ID id = null;
-        final Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = null;
-        try {
-            txn.start();
-            for (final Pair<String, Attribute[]> pair : _insertSqls) {
-                sql = pair.first();
-                final Attribute[] attrs = pair.second();
-
-                pstmt = txn.prepareAutoCloseStatement(sql, Statement.RETURN_GENERATED_KEYS);
-
-                int index = 1;
-                index = prepareAttributes(pstmt, entity, attrs, index);
-
-                pstmt.executeUpdate();
-
-                final ResultSet rs = pstmt.getGeneratedKeys();
-                if (id == null) {
-                    if (rs != null && rs.next()) {
-                        id = (ID)rs.getObject(1);
-                    }
-                    try {
-                        if (_idField != null) {
-                            if (id != null) {
-                                _idField.set(entity, id);
-                            } else {
-                                id = (ID)_idField.get(entity);
-                            }
-                        }
-                    } catch (final IllegalAccessException e) {
-                        throw new CloudRuntimeException("Yikes! ", e);
-                    }
-                }
-            }
-
-            if (_ecAttributes != null && _ecAttributes.size() > 0) {
-                HashMap<Attribute, Object> ecAttributes = new HashMap<Attribute, Object>();
-                for (Attribute attr : _ecAttributes) {
-                    Object ec = attr.field.get(entity);
-                    if (ec != null) {
-                        ecAttributes.put(attr, ec);
-                    }
-                }
-
-                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ecAttributes);
-            }
-            txn.commit();
-        } catch (final SQLException e) {
-            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
-                throw new EntityExistsException("Entity already exists: ", e);
-            } else {
-                throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-            }
-        } catch (IllegalArgumentException e) {
-            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
-        } catch (IllegalAccessException e) {
-            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
-        }
-
-        return _idField != null ? findByIdIncludingRemoved(id) : null;
-    }
-
-    protected void insertElementCollection(T entity, Attribute idAttribute, ID id, Map<Attribute, Object> ecAttributes) throws SQLException {
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-        for (Map.Entry<Attribute, Object> entry : ecAttributes.entrySet()) {
-            Attribute attr = entry.getKey();
-            Object obj = entry.getValue();
-
-            EcInfo ec = (EcInfo)attr.attache;
-            Enumeration en = null;
-            if (ec.rawClass == null) {
-                en = Collections.enumeration(Arrays.asList((Object[])obj));
-            } else {
-                en = Collections.enumeration((Collection)obj);
-            }
-            PreparedStatement pstmt = txn.prepareAutoCloseStatement(ec.clearSql);
-            prepareAttribute(1, pstmt, idAttribute, id);
-            pstmt.executeUpdate();
-
-            while (en.hasMoreElements()) {
-                pstmt = txn.prepareAutoCloseStatement(ec.insertSql);
-                if (ec.targetClass == Date.class) {
-                    pstmt.setString(1, DateUtil.getDateDisplayString(s_gmtTimeZone, (Date)en.nextElement()));
-                } else {
-                    pstmt.setObject(1, en.nextElement());
-                }
-                prepareAttribute(2, pstmt, idAttribute, id);
-                pstmt.executeUpdate();
-            }
-        }
-        txn.commit();
-    }
-
-    @DB(txn=false)
-    protected Object generateValue(final Attribute attr) {
-        if (attr.is(Attribute.Flag.Created) || attr.is(Attribute.Flag.Removed)) {
-            return new Date();
-        } else if (attr.is(Attribute.Flag.TableGV)) {
-            return null;
-            // Not sure what to do here.
-        } else if (attr.is(Attribute.Flag.AutoGV)) {
-            if (attr.columnName.equals(GenericDao.XID_COLUMN)) {
-                return UUID.randomUUID().toString();
-            }
-            assert (false) : "Auto generation is not supported.";
-            return null;
-        } else if (attr.is(Attribute.Flag.SequenceGV)) {
-            assert (false) : "Sequence generation is not supported.";
-            return null;
-        } else if (attr.is(Attribute.Flag.DC)) {
-            return _discriminatorValues.get(attr.columnName);
-        } else {
-            assert (false) : "Attribute can't be auto generated: " + attr.columnName;
-            return null;
-        }
-    }
-
-    @DB(txn=false)
-    protected void prepareAttribute(final int j, final PreparedStatement pstmt, final Attribute attr, Object value) throws SQLException {
-        if (attr.is(Attribute.Flag.DaoGenerated) && value == null) {
-            value = generateValue(attr);
-            if (attr.field == null) {
-                pstmt.setObject(j, value);
-                return;
-            }
-        }
-        if (attr.field.getType() == String.class) {
-            final String str = (String)value;
-            if (str == null) {
-                pstmt.setString(j, null);
-                return;
-            }
-            final Column column = attr.field.getAnnotation(Column.class);
-            final int length = column != null ? column.length() : 255;
-
-            // to support generic localization, utilize MySql UTF-8 support
-            if (length < str.length()) {
-                try {
-                    if (attr.is(Attribute.Flag.Encrypted)){
-                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str.substring(0, column.length())).getBytes("UTF-8"));
-                    } else {
-                        pstmt.setBytes(j, str.substring(0, column.length()).getBytes("UTF-8"));
-                    }
-                } catch (UnsupportedEncodingException e) {
-                    // no-way it can't support UTF-8 encoding
-                    assert(false);
-                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
-                }
-            } else {
-                try {
-                    if (attr.is(Attribute.Flag.Encrypted)){
-                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str).getBytes("UTF-8"));
-                    } else {
-                        pstmt.setBytes(j, str.getBytes("UTF-8"));
-                    }
-                } catch (UnsupportedEncodingException e) {
-                    // no-way it can't support UTF-8 encoding
-                    assert(false);
-                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
-                }
-            }
-        } else if (attr.field.getType() == Date.class) {
-            final Date date = (Date)value;
-            if (date == null) {
-                pstmt.setObject(j, null);
-                return;
-            }
-            if (attr.is(Attribute.Flag.Date)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
-            } else if (attr.is(Attribute.Flag.TimeStamp)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
-            } else if (attr.is(Attribute.Flag.Time)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
-            }
-        } else if (attr.field.getType() == Calendar.class) {
-            final Calendar cal = (Calendar)value;
-            if (cal == null) {
-                pstmt.setObject(j, null);
-                return;
-            }
-            if (attr.is(Attribute.Flag.Date)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
-            } else if (attr.is(Attribute.Flag.TimeStamp)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
-            } else if (attr.is(Attribute.Flag.Time)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
-            }
-        } else if (attr.field.getType().isEnum()) {
-            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
-            final EnumType type = (enumerated == null) ? EnumType.STRING : enumerated.value();
-            if (type == EnumType.STRING) {
-                pstmt.setString(j, value == null ? null :  value.toString());
-            } else if (type == EnumType.ORDINAL) {
-                if (value == null) {
-                    pstmt.setObject(j, null);
-                } else {
-                    pstmt.setInt(j, ((Enum<?>)value).ordinal());
-                }
-            }
-        } else if (attr.field.getType() == URI.class) {
-            pstmt.setString(j, value == null ? null : value.toString());
-        } else if (attr.field.getType() == URL.class) {
-            pstmt.setURL(j, (URL)value);
-        } else if (attr.field.getType() == byte[].class) {
-            pstmt.setBytes(j, (byte[])value);
-        } else if (attr.field.getType() == Ip.class) {
-            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
-            final EnumType type = (enumerated == null) ? EnumType.ORDINAL : enumerated.value();
-            if (type == EnumType.STRING) {
-                pstmt.setString(j, value == null ? null : value.toString());
-            } else if (type == EnumType.ORDINAL) {
-                if (value == null) {
-                    pstmt.setObject(j, null);
-                } else {
-                    pstmt.setLong(j, (value instanceof Ip) ? ((Ip)value).longValue() : NetUtils.ip2Long((String)value));
-                }
-            }
-        } else {
-            pstmt.setObject(j, value);
-        }
-    }
-
-    @DB(txn=false)
-    protected int prepareAttributes(final PreparedStatement pstmt, final Object entity, final Attribute[] attrs, final int index) throws SQLException {
-        int j = 0;
-        for (int i = 0; i < attrs.length; i++) {
-            j = i + index;
-            try {
-                prepareAttribute(j, pstmt, attrs[i], attrs[i].field != null ? attrs[i].field.get(entity) : null);
-            } catch (final IllegalArgumentException e) {
-                throw new CloudRuntimeException("IllegalArgumentException", e);
-            } catch (final IllegalAccessException e) {
-                throw new CloudRuntimeException("IllegalArgumentException", e);
-            }
-        }
-
-        return j;
-    }
-
-    @SuppressWarnings("unchecked") @DB(txn=false)
-    protected T toEntityBean(final ResultSet result, final boolean cache) throws SQLException {
-        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
-
-        toEntityBean(result, entity);
-
-        if (cache && _cache != null) {
-            try {
-                _cache.put(new Element(_idField.get(entity), entity));
-            } catch (final Exception e) {
-                s_logger.debug("Can't put it in the cache", e);
-            }
-        }
-
-        return entity;
-    }
-
-    @DB(txn=false)
-    protected T toVO(ResultSet result, boolean cache) throws SQLException {
-        T entity;
-        try {
-            entity = _entityBeanType.newInstance();
-        } catch (InstantiationException e1) {
-            throw new CloudRuntimeException("Unable to instantiate entity", e1);
-        } catch (IllegalAccessException e1) {
-            throw new CloudRuntimeException("Illegal Access", e1);
-        }
-        toEntityBean(result, entity);
-        if (cache && _cache != null) {
-            try {
-                _cache.put(new Element(_idField.get(entity), entity));
-            } catch (final Exception e) {
-                s_logger.debug("Can't put it in the cache", e);
-            }
-        }
-
-        return entity;
-    }
-
-    @DB(txn=false)
-    protected void toEntityBean(final ResultSet result, final T entity) throws SQLException {
-        ResultSetMetaData meta = result.getMetaData();
-        for (int index = 1, max = meta.getColumnCount(); index <= max; index++) {
-            setField(entity, result, meta, index);
-        }
-        for (Attribute attr : _ecAttributes) {
-            loadCollection(entity, attr);
-        }
-    }
-
-    @DB(txn = true)
-    @SuppressWarnings("unchecked")
-    protected void loadCollection(T entity, Attribute attr)  {
-        EcInfo ec = (EcInfo)attr.attache;
-
-        Transaction txn = Transaction.currentTxn();
-        ResultSet rs = null;
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareStatement(ec.selectSql);
-            pstmt.setObject(1, _idField.get(entity));
-            rs = pstmt.executeQuery();
-            ArrayList lst = new ArrayList();
-            if (ec.targetClass == Integer.class) {
-                while (rs.next()) {
-                    lst.add(rs.getInt(1));
-                }
-            } else if (ec.targetClass == Long.class) {
-                while (rs.next()) {
-                    lst.add(rs.getLong(1));
-                }
-            } else if (ec.targetClass == String.class) {
-                while (rs.next()) {
-                    lst.add(rs.getString(1));
-                }
-            } else if (ec.targetClass == Short.class) {
-                while (rs.next()) {
-                    lst.add(rs.getShort(1));
-                }
-            } else if (ec.targetClass == Date.class) {
-                while (rs.next()) {
-                    lst.add(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(1)));
-                }
-            } else if (ec.targetClass == Boolean.class) {
-                while (rs.next()) {
-                    lst.add(rs.getBoolean(1));
-                }
-            } else {
-                assert (false) : "You'll need to add more classeses";
-            }
-
-            if (ec.rawClass == null) {
-                Object[] array = (Object[])Array.newInstance(ec.targetClass);
-                lst.toArray(array);
-                try {
-                    attr.field.set(entity, array);
-                } catch (IllegalArgumentException e) {
-                    throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
-                } catch (IllegalAccessException e) {
-                    throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
-                }
-            } else {
-                try {
-                    Collection coll = (Collection)ec.rawClass.newInstance();
-                    coll.addAll(lst);
-                    attr.field.set(entity, coll);
-                } catch (IllegalAccessException e) {
-                    throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
-                } catch (InstantiationException e) {
-                    throw new CloudRuntimeException("Never should happen", e);
-                }
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Error executing " + pstmt, e);
-        } catch (IllegalArgumentException e) {
-            throw new CloudRuntimeException("Error executing " + pstmt, e);
-        } catch (IllegalAccessException e) {
-            throw new CloudRuntimeException("Error executing " + pstmt, e);
-        } finally {
-            try {
-                if (rs != null) {
-                    rs.close();
-                }
-                if (pstmt != null) {
-                    pstmt.close();
-                }
-            } catch (SQLException e) {
-                s_logger.error("Why are we getting an exception at close? ", e);
-            }
-        }
-    }
-
-    @Override
-    public void expunge() {
-        if (_removed == null) {
-            return;
-        }
-        final StringBuilder sql = new StringBuilder("DELETE FROM ");
-        sql.append(_table).append(" WHERE ").append(_removed.first()).append(" IS NOT NULL");
-        final Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(sql.toString());
-
-            pstmt.executeUpdate();
-            txn.commit();
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on " + pstmt, e);
-        }
-    }
-
-    @DB(txn=false)
-    protected void setField(final Object entity, final ResultSet rs, ResultSetMetaData meta, final int index) throws SQLException {
-        Attribute attr = _allColumns.get(new Pair<String, String>(meta.getTableName(index), meta.getColumnName(index)));
-        if ( attr == null ){
-            // work around for mysql bug to return original table name instead of view name in db view case
-            Table tbl = entity.getClass().getSuperclass().getAnnotation(Table.class);
-            if ( tbl != null ){
-                attr = _allColumns.get(new Pair<String, String>(tbl.name(), meta.getColumnLabel(index)));
-            }
-        }
-        assert (attr != null) : "How come I can't find " + meta.getCatalogName(index) + "." + meta.getColumnName(index);
-        setField(entity, attr.field, rs, index);
-    }
-
-    @Override
-    public boolean remove(final ID id) {
-        if (_removeSql == null) {
-            return expunge(id);
-        }
-
-        final Transaction txn = Transaction.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(_removeSql.first());
-            final Attribute[] attrs = _removeSql.second();
-            prepareAttribute(1, pstmt, attrs[attrs.length - 1], null);
-            for (int i = 0; i < attrs.length - 1; i++) {
-                prepareAttribute(i + 2, pstmt, attrs[i], id);
-            }
-
-            final int result = pstmt.executeUpdate();
-            txn.commit();
-            if (_cache != null) {
-                _cache.remove(id);
-            }
-            return result > 0;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    @Override
-    public int remove(SearchCriteria<T> sc) {
-        if (_removeSql == null) {
-            return expunge(sc);
-        }
-
-        T vo = createForUpdate();
-        UpdateBuilder ub = getUpdateBuilder(vo);
-
-        ub.set(vo, _removed.second(), new Date());
-        return update(ub, sc, null);
-    }
-
-    protected Cache _cache;
-    @DB(txn=false)
-    protected void createCache(final Map<String, ? extends Object> params) {
-        final String value = (String)params.get("cache.size");
-
-        if (value != null) {
-            final CacheManager cm = CacheManager.create();
-            final int maxElements = NumbersUtil.parseInt(value, 0);
-            final int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300);
-            final int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300);
-            _cache = new Cache(getName(), maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle);
-            cm.addCache(_cache);
-            s_logger.info("Cache created: " + _cache.toString());
-        } else {
-            _cache = null;
-        }
-    }
-
-    @Override @DB(txn=false)
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-
-        final String value = (String)params.get("lock.timeout");
-        _timeoutSeconds = NumbersUtil.parseInt(value, 300);
-
-        createCache(params);
-        final boolean load = Boolean.parseBoolean((String)params.get("cache.preload"));
-        if (load) {
-            listAll();
-        }
-
-        return true;
-    }
-
-    @DB(txn=false)
-    public static <T> UpdateBuilder getUpdateBuilder(final T entityObject) {
-        final Factory factory = (Factory)entityObject;
-        assert(factory != null);
-        return (UpdateBuilder)factory.getCallback(1);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override @DB(txn=false)
-    public SearchBuilder<T> createSearchBuilder() {
-        final T entity = (T)_searchEnhancer.create();
-        final Factory factory = (Factory)entity;
-        SearchBuilder<T> builder = new SearchBuilder<T>(entity, _allAttributes);
-        factory.setCallback(0, builder);
-        return builder;
-    }
-
-    @Override @DB(txn=false)
-    public SearchCriteria<T> createSearchCriteria() {
-        SearchBuilder<T> builder = createSearchBuilder();
-        return builder.create();
-    }
-
-    @Override @DB(txn=false)
-    public <K> SearchCriteria2 createSearchCriteria2(Class<K> resultType) {
-        final T entity = (T)_searchEnhancer.create();
-        final Factory factory = (Factory)entity;
-        SearchCriteria2 sc = new SearchCriteria2(entity, resultType, _allAttributes, this);
-        factory.setCallback(0, sc);
-        return sc;
-    }
-
-    @Override @DB(txn=false)
-    public SearchCriteria2 createSearchCriteria2() {
-        final T entity = (T)_searchEnhancer.create();
-        final Factory factory = (Factory)entity;
-        SearchCriteria2 sc = new SearchCriteria2(entity, entity.getClass(), _allAttributes, this);
-        factory.setCallback(0, sc);
-        return sc;
-    }
-
-    @Override
-    public int getRegionId(){
-    	return Transaction.s_region_id;
-    }
-
-    public Integer getCount(SearchCriteria<T> sc) {
-        String clause = sc != null ? sc.getWhereClause() : null;
-        if (clause != null && clause.length() == 0) {
-            clause = null;
-        }
-
-        final StringBuilder str = createCountSelect(sc, clause != null);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        if (sc != null) {
-            joins = sc.getJoins();
-            if (joins != null) {
-                addJoins(str, joins);
-            }
-        }
-
-        // we have to disable group by in getting count, since count for groupBy clause will be different.
-        //List<Object> groupByValues = addGroupBy(str, sc);
-        final Transaction txn = Transaction.currentTxn();
-        final String sql = str.toString();
-
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 0;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(++i, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            /*
-            if (groupByValues != null) {
-                for (Object value : groupByValues) {
-                    pstmt.setObject(i++, value);
-                }
-            }
-             */
-
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                return rs.getInt(1);
-            }
-            return 0;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @DB(txn=false)
-    protected StringBuilder createCountSelect(SearchCriteria<?> sc, final boolean whereClause) {
-        StringBuilder sql = new StringBuilder(_count);
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-}


[05/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java b/utils/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
deleted file mode 100755
index 9b13eb8..0000000
--- a/utils/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
+++ /dev/null
@@ -1,427 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.crypt;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
-import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
-import org.jasypt.exceptions.EncryptionOperationNotPossibleException;
-import org.jasypt.properties.EncryptableProperties;
-
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-
-/*
- * EncryptionSecretKeyChanger updates Management Secret Key / DB Secret Key or both.
- * DB secret key is validated against the key in db.properties
- * db.properties is updated with values encrypted using new MS secret key
- * DB data migrated using new DB secret key
- */
-public class EncryptionSecretKeyChanger {
-
-	private StandardPBEStringEncryptor oldEncryptor = new StandardPBEStringEncryptor();
-	private StandardPBEStringEncryptor newEncryptor = new StandardPBEStringEncryptor();
-	private static final String keyFile = "/etc/cloudstack/management/key";
-
-	public static void main(String[] args){
-		List<String> argsList = Arrays.asList(args);
-		Iterator<String> iter = argsList.iterator();
-		String oldMSKey = null;
-		String oldDBKey = null;
-		String newMSKey = null; 
-		String newDBKey = null;
-
-		//Parse command-line args
-		while (iter.hasNext()) {
-			String arg = iter.next();
-			// Old MS Key
-			if (arg.equals("-m")) {
-				oldMSKey = iter.next();
-			}
-			// Old DB Key
-			if (arg.equals("-d")) {
-				oldDBKey = iter.next();
-			}
-			// New MS Key
-			if (arg.equals("-n")) {
-				newMSKey = iter.next();
-			}
-			// New DB Key
-			if (arg.equals("-e")) {
-				newDBKey = iter.next();
-			}
-		}
-
-		if(oldMSKey == null || oldDBKey ==null){
-			System.out.println("Existing MS secret key or DB secret key is not provided");
-			usage();
-			return;
-		}
-
-		if(newMSKey == null && newDBKey ==null){
-			System.out.println("New MS secret key and DB secret are both not provided");
-			usage();
-			return;
-		}
-
-		final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties");
-		final Properties dbProps;
-		EncryptionSecretKeyChanger keyChanger = new EncryptionSecretKeyChanger();
-		StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
-		keyChanger.initEncryptor(encryptor, oldMSKey);
-		dbProps = new EncryptableProperties(encryptor);
-		PropertiesConfiguration backupDBProps = null;
-
-		System.out.println("Parsing db.properties file");
-		try {
-			dbProps.load(new FileInputStream(dbPropsFile));
-			backupDBProps = new PropertiesConfiguration(dbPropsFile);
-		} catch (FileNotFoundException e) {
-			System.out.println("db.properties file not found while reading DB secret key" +e.getMessage());
-		} catch (IOException e) {
-			System.out.println("Error while reading DB secret key from db.properties" +e.getMessage());
-		} catch (ConfigurationException e) {
-			e.printStackTrace();
-		}
-		
-		String dbSecretKey = null;
-		try {
-			dbSecretKey = dbProps.getProperty("db.cloud.encrypt.secret");
-		} catch (EncryptionOperationNotPossibleException e) {
-			System.out.println("Failed to decrypt existing DB secret key from db.properties. "+e.getMessage());
-			return;
-		}
-		
-		if(!oldDBKey.equals(dbSecretKey)){
-			System.out.println("Incorrect MS Secret Key or DB Secret Key");
-			return;
-		}
-
-		System.out.println("Secret key provided matched the key in db.properties");
-		final String encryptionType = dbProps.getProperty("db.cloud.encryption.type");
-		
-		if(newMSKey == null){
-			System.out.println("No change in MS Key. Skipping migrating db.properties");
-		} else {
-			if(!keyChanger.migrateProperties(dbPropsFile, dbProps, newMSKey, newDBKey)){
-				System.out.println("Failed to update db.properties");
-				return;
-			} else {
-				//db.properties updated successfully
-				if(encryptionType.equals("file")){
-					//update key file with new MS key
-					try {
-						FileWriter fwriter = new FileWriter(keyFile);
-						BufferedWriter bwriter = new BufferedWriter(fwriter); 
-						bwriter.write(newMSKey);
-						bwriter.close();
-					} catch (IOException e) {
-						System.out.println("Failed to write new secret to file. Please update the file manually");
-					} 
-				}
-			}
-		}
-		
-		boolean success = false;
-		if(newDBKey == null || newDBKey.equals(oldDBKey)){
-			System.out.println("No change in DB Secret Key. Skipping Data Migration");
-		} else {
-			EncryptionSecretKeyChecker.initEncryptorForMigration(oldMSKey);
-			try {
-				success = keyChanger.migrateData(oldDBKey, newDBKey);
-			} catch (Exception e) {
-				System.out.println("Error during data migration");
-				e.printStackTrace();
-				success = false;
-			}
-		}
-		
-		if(success){
-			System.out.println("Successfully updated secret key(s)");
-		}
-		else {
-			System.out.println("Data Migration failed. Reverting db.properties");
-			//revert db.properties
-			try {
-				backupDBProps.save();
-			} catch (ConfigurationException e) {
-				e.printStackTrace();
-			}
-			if(encryptionType.equals("file")){
-				//revert secret key in file
-				try {
-					FileWriter fwriter = new FileWriter(keyFile);
-					BufferedWriter bwriter = new BufferedWriter(fwriter); 
-					bwriter.write(oldMSKey);
-					bwriter.close();
-				} catch (IOException e) {
-					System.out.println("Failed to revert to old secret to file. Please update the file manually");
-				} 
-			}
-		}
-	}
-	
-	private boolean migrateProperties(File dbPropsFile, Properties dbProps, String newMSKey, String newDBKey){
-		System.out.println("Migrating db.properties..");
-		StandardPBEStringEncryptor msEncryptor = new StandardPBEStringEncryptor();;
-		initEncryptor(msEncryptor, newMSKey);
-		
-		try {
-			PropertiesConfiguration newDBProps = new PropertiesConfiguration(dbPropsFile);
-			if(newDBKey!=null && !newDBKey.isEmpty()){
-				newDBProps.setProperty("db.cloud.encrypt.secret", "ENC("+msEncryptor.encrypt(newDBKey)+")");
-			}
-			String prop = dbProps.getProperty("db.cloud.password");
-			if(prop!=null && !prop.isEmpty()){
-				newDBProps.setProperty("db.cloud.password", "ENC("+msEncryptor.encrypt(prop)+")");
-			}
-			prop = dbProps.getProperty("db.usage.password");
-			if(prop!=null && !prop.isEmpty()){
-				newDBProps.setProperty("db.usage.password", "ENC("+msEncryptor.encrypt(prop)+")");
-			}
-			newDBProps.save(dbPropsFile.getAbsolutePath());
-		} catch (Exception e) { 		
-			e.printStackTrace();
-			return false;
-		}
-		System.out.println("Migrating db.properties Done.");
-		return true;
-	}
-
-	private boolean migrateData(String oldDBKey, String newDBKey){
-		System.out.println("Begin Data migration");
-		initEncryptor(oldEncryptor, oldDBKey);
-		initEncryptor(newEncryptor, newDBKey);
-		System.out.println("Initialised Encryptors");
-		
-		Transaction txn = Transaction.open("Migrate");
-		txn.start();
-		try {
-			Connection conn;
-			try {
-				conn = txn.getConnection();
-			} catch (SQLException e) {
-				throw new CloudRuntimeException("Unable to migrate encrypted data in the database", e);
-			}
-
-			migrateConfigValues(conn);
-			migrateHostDetails(conn);
-			migrateVNCPassword(conn);
-			migrateUserCredentials(conn);
-
-			txn.commit();
-		} finally {
-			txn.close();
-		}
-		System.out.println("End Data migration");
-		return true;
-	}
-
-	private void initEncryptor(StandardPBEStringEncryptor encryptor, String secretKey){
-		encryptor.setAlgorithm("PBEWithMD5AndDES");
-		SimpleStringPBEConfig stringConfig = new SimpleStringPBEConfig();
-		stringConfig.setPassword(secretKey);
-		encryptor.setConfig(stringConfig);
-	}
-
-	private String migrateValue(String value){
-		if(value ==null || value.isEmpty()){
-			return value;
-		}
-		String decryptVal = oldEncryptor.decrypt(value);
-		return newEncryptor.encrypt(decryptVal);
-	}
-
-	private void migrateConfigValues(Connection conn) {
-		System.out.println("Begin migrate config values");
-		PreparedStatement pstmt = null;
-		ResultSet rs = null;
-		try {
-			pstmt = conn.prepareStatement("select name, value from configuration where category in ('Hidden', 'Secure')");
-			rs = pstmt.executeQuery();
-			while (rs.next()) {
-				String name = rs.getString(1);
-				String value = rs.getString(2);
-				if(value == null || value.isEmpty()){
-					continue;
-				}
-				String encryptedValue = migrateValue(value);
-				pstmt = conn.prepareStatement("update configuration set value=? where name=?");
-				pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
-				pstmt.setString(2, name);
-				pstmt.executeUpdate();
-			}
-		} catch (SQLException e) {
-			throw new CloudRuntimeException("Unable to update configuration values ", e);
-		} catch (UnsupportedEncodingException e) {
-			throw new CloudRuntimeException("Unable to update configuration values ", e);
-		} finally {
-			try {
-				if (rs != null) {
-					rs.close(); 
-				}
-
-				if (pstmt != null) {
-					pstmt.close();
-				}
-			} catch (SQLException e) {
-			}
-		}
-		System.out.println("End migrate config values");
-	}
-
-	private void migrateHostDetails(Connection conn) {
-		System.out.println("Begin migrate host details");
-		PreparedStatement pstmt = null;
-		ResultSet rs = null;
-		try {
-			pstmt = conn.prepareStatement("select id, value from host_details where name = 'password'");
-			rs = pstmt.executeQuery();
-			while (rs.next()) {
-				long id = rs.getLong(1);
-				String value = rs.getString(2);
-				if(value == null || value.isEmpty()){
-					continue;
-				}
-				String encryptedValue = migrateValue(value);
-				pstmt = conn.prepareStatement("update host_details set value=? where id=?");
-				pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
-				pstmt.setLong(2, id);
-				pstmt.executeUpdate();
-			}
-		} catch (SQLException e) {
-			throw new CloudRuntimeException("Unable update host_details values ", e);
-		} catch (UnsupportedEncodingException e) {
-			throw new CloudRuntimeException("Unable update host_details values ", e);
-		} finally {
-			try {
-				if (rs != null) {
-					rs.close(); 
-				}
-
-				if (pstmt != null) {
-					pstmt.close();
-				}
-			} catch (SQLException e) {
-			}
-		}
-		System.out.println("End migrate host details");
-	}
-
-	private void migrateVNCPassword(Connection conn) {
-		System.out.println("Begin migrate VNC password");
-		PreparedStatement pstmt = null;
-		ResultSet rs = null;
-		try {
-			pstmt = conn.prepareStatement("select id, vnc_password from vm_instance");
-			rs = pstmt.executeQuery();
-			while (rs.next()) {
-				long id = rs.getLong(1);
-				String value = rs.getString(2);
-				if(value == null || value.isEmpty()){
-					continue;
-				}
-				String encryptedValue = migrateValue(value);
-				pstmt = conn.prepareStatement("update vm_instance set vnc_password=? where id=?");
-				pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
-				pstmt.setLong(2, id);
-				pstmt.executeUpdate();
-			}
-		} catch (SQLException e) {
-			throw new CloudRuntimeException("Unable update vm_instance vnc_password ", e);
-		} catch (UnsupportedEncodingException e) {
-			throw new CloudRuntimeException("Unable update vm_instance vnc_password ", e);
-		} finally {
-			try {
-				if (rs != null) {
-					rs.close(); 
-				}
-
-				if (pstmt != null) {
-					pstmt.close();
-				}
-			} catch (SQLException e) {
-			}
-		}
-		System.out.println("End migrate VNC password");
-	}
-
-	private void migrateUserCredentials(Connection conn) {
-		System.out.println("Begin migrate user credentials");
-		PreparedStatement pstmt = null;
-		ResultSet rs = null;
-		try {
-			pstmt = conn.prepareStatement("select id, secret_key from user");
-			rs = pstmt.executeQuery();
-			while (rs.next()) {
-				long id = rs.getLong(1);
-				String secretKey = rs.getString(2);
-				if(secretKey == null || secretKey.isEmpty()){
-					continue;
-				}
-				String encryptedSecretKey = migrateValue(secretKey);
-				pstmt = conn.prepareStatement("update user set secret_key=? where id=?");
-				pstmt.setBytes(1, encryptedSecretKey.getBytes("UTF-8"));
-				pstmt.setLong(2, id);
-				pstmt.executeUpdate();
-			}
-		} catch (SQLException e) {
-			throw new CloudRuntimeException("Unable update user secret key ", e);
-		} catch (UnsupportedEncodingException e) {
-			throw new CloudRuntimeException("Unable update user secret key ", e);
-		} finally {
-			try {
-				if (rs != null) {
-					rs.close(); 
-				}
-
-				if (pstmt != null) {
-					pstmt.close();
-				}
-			} catch (SQLException e) {
-			}
-		}
-		System.out.println("End migrate user credentials");
-	}
-
-	private static void usage(){
-		System.out.println("Usage: \tEncryptionSecretKeyChanger \n" +
-				"\t\t-m <Mgmt Secret Key> \n" +
-				"\t\t-d <DB Secret Key> \n" +
-				"\t\t-n [New Mgmt Secret Key] \n" +
-				"\t\t-e [New DB Secret Key]");
-	}
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/Attribute.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Attribute.java b/utils/src/com/cloud/utils/db/Attribute.java
deleted file mode 100755
index 22fd969..0000000
--- a/utils/src/com/cloud/utils/db/Attribute.java
+++ /dev/null
@@ -1,253 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Field;
-
-import javax.persistence.AttributeOverride;
-import javax.persistence.Column;
-import javax.persistence.ElementCollection;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-/**
- * The Java annotation are somewhat incomplete.  This gives better information
- * about exactly what each field has.
- *
- */
-public class Attribute {
-    public enum Flag {
-        Insertable(0x01),
-        Updatable(0x02),
-        Nullable(0x04),
-        DaoGenerated(0x08),
-        DbGenerated(0x10),
-        Embedded(0x20),
-        Id(0x40),
-        Selectable(0x80),
-        Time(0x100),
-        Date(0x200),
-        TimeStamp(0x400),
-        SequenceGV(0x1000),
-        TableGV(0x2000),
-        AutoGV(0x4000),
-        Created(0x10000),
-        Removed(0x20000),
-        DC(0x40000),
-        CharDT(0x100000),
-        StringDT(0x200000),
-        IntegerDT(0x400000),
-        Encrypted(0x800000);
-
-        int place;
-        Flag(int place) {
-            this.place = place;
-        }
-
-        public int place() {
-            return place;
-        }
-
-        public boolean check(int value) {
-            return (value & place) == place;
-        }
-
-        public int setTrue(int value) {
-            return (value | place);
-        }
-
-        public int setFalse(int value) {
-            return (value & ~place);
-        }
-    }
-
-    protected String table;
-    protected String columnName;
-    protected Field field;
-    protected int flags;
-    protected Column column;
-    protected Object attache;
-
-    public Attribute(Class<?> clazz, AttributeOverride[] overrides, Field field, String tableName, boolean isEmbedded, boolean isId) {
-        this.field = field;
-        flags = 0;
-        table = tableName;
-        setupColumnInfo(clazz, overrides, tableName, isEmbedded, isId);
-    }
-
-    public Attribute(String table, String columnName) {
-        this.table = table;
-        this.columnName = columnName;
-        this.field = null;
-        this.column = null;
-    }
-
-    protected void setupColumnInfo(Class<?> clazz, AttributeOverride[] overrides, String tableName, boolean isEmbedded, boolean isId) {
-        flags = Flag.Selectable.setTrue(flags);
-        GeneratedValue gv = field.getAnnotation(GeneratedValue.class);
-        if (gv != null) {
-            if (gv.strategy() == GenerationType.IDENTITY) {
-                flags = Flag.DbGenerated.setTrue(flags);
-            } else if (gv.strategy() == GenerationType.SEQUENCE) {
-                assert (false) : "Sequence generation not supported.";
-                flags = Flag.DaoGenerated.setTrue(flags);
-                flags = Flag.Insertable.setTrue(flags);
-                flags = Flag.SequenceGV.setTrue(flags);
-            } else if (gv.strategy() == GenerationType.TABLE) {
-                flags = Flag.DaoGenerated.setTrue(flags);
-                flags = Flag.Insertable.setTrue(flags);
-                flags = Flag.TableGV.setTrue(flags);
-            } else if (gv.strategy() == GenerationType.AUTO) {
-                flags = Flag.DaoGenerated.setTrue(flags);
-                flags = Flag.Insertable.setTrue(flags);
-                flags = Flag.AutoGV.setTrue(flags);
-            }
-        }
-
-        if (isEmbedded) {
-            flags = Flag.Embedded.setTrue(flags);
-        }
-
-        if (isId) {
-            flags = Flag.Id.setTrue(flags);
-        } else {
-            Id id = field.getAnnotation(Id.class);
-            if (id != null) {
-                flags = Flag.Id.setTrue(flags);
-            }
-        }
-        column = field.getAnnotation(Column.class);
-        if (gv == null) {
-            if (column == null || (column.insertable() && column.table().length() == 0)) {
-                flags = Flag.Insertable.setTrue(flags);
-            }
-            if (column == null || (column.updatable() && column.table().length() == 0)) {
-                flags = Flag.Updatable.setTrue(flags);
-            }
-            if (column == null || column.nullable()) {
-                flags = Flag.Nullable.setTrue(flags);
-            }
-            Encrypt encrypt = field.getAnnotation(Encrypt.class);
-            if (encrypt != null && encrypt.encrypt()) {
-                flags = Flag.Encrypted.setTrue(flags);
-            }
-        }
-        ElementCollection ec = field.getAnnotation(ElementCollection.class);
-        if (ec != null) {
-            flags = Flag.Insertable.setFalse(flags);
-            flags = Flag.Selectable.setFalse(flags);
-        }
-
-        Temporal temporal = field.getAnnotation(Temporal.class);
-        if (temporal != null) {
-            if (temporal.value() == TemporalType.DATE) {
-                flags = Flag.Date.setTrue(flags);
-            } else if (temporal.value() == TemporalType.TIME) {
-                flags = Flag.Time.setTrue(flags);
-            } else if (temporal.value() == TemporalType.TIMESTAMP) {
-                flags = Flag.TimeStamp.setTrue(flags);
-            }
-        }
-
-        if (column != null && column.table().length() > 0) {
-            table = column.table();
-        }
-
-        columnName = DbUtil.getColumnName(field, overrides);
-    }
-
-    public final boolean isInsertable() {
-        return Flag.Insertable.check(flags);
-    }
-
-    public final boolean isUpdatable() {
-        return Flag.Updatable.check(flags);
-    }
-
-    public final boolean isNullable() {
-        return Flag.Nullable.check(flags);
-    }
-
-    public final boolean isId() {
-        return Flag.Id.check(flags);
-    }
-
-    public final boolean isSelectable() {
-        return Flag.Selectable.check(flags);
-    }
-
-    public final boolean is(Flag flag) {
-        return flag.check(flags);
-    }
-
-    public final void setTrue(Flag flag) {
-        flags = flag.setTrue(flags);
-    }
-
-    public final void setFalse(Flag flag) {
-        flags = flag.setFalse(flags);
-    }
-
-    public final boolean isEncrypted() {
-        return Flag.Encrypted.check(flags);
-    }
-
-    public Field getField() {
-        return field;
-    }
-
-    public Object get(Object entity) {
-        try {
-            return field.get(entity);
-        } catch (IllegalAccessException e) {
-            assert (false) : "How did we get here?";
-            return null;
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        return columnName.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof Attribute)) {
-            return false;
-        }
-
-        Attribute that = (Attribute)obj;
-
-        return columnName.equals(that.columnName) && table.equals(that.table);
-    }
-
-    @Override
-    public String toString() {
-        return table + "." + columnName;
-    }
-
-    public String getColumnName() {
-        return columnName;
-    }
-
-    public void setColumnName(String columnName) {
-        this.columnName = columnName;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/ConnectionConcierge.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/ConnectionConcierge.java b/utils/src/com/cloud/utils/db/ConnectionConcierge.java
deleted file mode 100644
index 0294334..0000000
--- a/utils/src/com/cloud/utils/db/ConnectionConcierge.java
+++ /dev/null
@@ -1,223 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.management.StandardMBean;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.mgmt.JmxUtil;
-
-/**
- * ConnectionConcierge keeps stand alone database connections alive.  This is
- * needs someone to keep that database connection from being garbage collected
- * 
- */
-public class ConnectionConcierge {
-
-    static final Logger s_logger = Logger.getLogger(ConnectionConcierge.class);
-
-    static final ConnectionConciergeManager s_mgr = new ConnectionConciergeManager();
-
-    Connection _conn;
-    String _name;
-    boolean _keepAlive;
-    boolean _autoCommit;
-    int _isolationLevel;
-    int _holdability;
-
-    public ConnectionConcierge(String name, Connection conn, boolean keepAlive) {
-        _name = name + s_mgr.getNextId();
-        _keepAlive = keepAlive;
-        try {
-            _autoCommit = conn.getAutoCommit();
-            _isolationLevel = conn.getTransactionIsolation();
-            _holdability = conn.getHoldability();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to get information from the connection object", e);
-        }
-        reset(conn);
-    }
-
-    public void reset(Connection conn) {
-        try {
-            release();
-        } catch (Throwable th) {
-            s_logger.error("Unable to release a connection", th);
-        }
-        _conn = conn;
-        try {
-            _conn.setAutoCommit(_autoCommit);
-            _conn.setHoldability(_holdability);
-            _conn.setTransactionIsolation(_isolationLevel);
-        } catch (SQLException e) {
-            s_logger.error("Unable to release a connection", e);
-        }
-        s_mgr.register(_name, this);
-        s_logger.debug("Registering a database connection for " + _name);
-    }
-
-    public final Connection conn() {
-        return _conn;
-    }
-
-    public void release() {
-        s_mgr.unregister(_name);
-        try {
-            if (_conn != null) {
-                _conn.close();
-            }
-            _conn = null;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Problem in closing a connection", e);
-        }
-    }
-
-    @Override
-    protected void finalize() throws Exception {
-        if (_conn != null) {
-            release();
-        }
-    }
-
-    public boolean keepAlive() {
-        return _keepAlive;
-    }
-
-    protected static class ConnectionConciergeManager extends StandardMBean implements ConnectionConciergeMBean {
-        ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ConnectionKeeper"));
-        final ConcurrentHashMap<String, ConnectionConcierge> _conns = new ConcurrentHashMap<String, ConnectionConcierge>();
-        final AtomicInteger _idGenerator = new AtomicInteger();
-
-        ConnectionConciergeManager() {
-            super(ConnectionConciergeMBean.class, false);
-            resetKeepAliveTask(20);
-            try {
-                JmxUtil.registerMBean("DB Connections", "DB Connections", this);
-            } catch (Exception e) {
-                s_logger.error("Unable to register mbean", e);
-            }
-        }
-
-        public Integer getNextId() {
-            return _idGenerator.incrementAndGet();
-        }
-
-        public void register(String name, ConnectionConcierge concierge) {
-            _conns.put(name, concierge);
-        }
-
-        public void unregister(String name) {
-            _conns.remove(name);
-        }
-
-        protected String testValidity(String name, Connection conn) {
-            PreparedStatement pstmt = null;
-            try {
-                if (conn != null) {
-                    pstmt = conn.prepareStatement("SELECT 1");
-                    pstmt.executeQuery();
-                }
-                return null;
-            } catch (Throwable th) {
-                s_logger.error("Unable to keep the db connection for " + name, th);
-                return th.toString();
-            } finally {
-                if (pstmt != null) {
-                    try {
-                        pstmt.close();
-                    } catch (SQLException e) {
-                    }
-                }
-            }
-        }
-
-        @Override
-        public List<String> testValidityOfConnections() {
-            ArrayList<String> results = new ArrayList<String>(_conns.size());
-            for (Map.Entry<String, ConnectionConcierge> entry : _conns.entrySet()) {
-                String result = testValidity(entry.getKey(), entry.getValue().conn());
-                results.add(entry.getKey() + "=" + (result == null ? "OK" : result));
-            }
-            return results;
-        }
-
-        @Override
-        public String resetConnection(String name) {
-            ConnectionConcierge concierge = _conns.get(name);
-            if (concierge == null) {
-                return "Not Found";
-            }
-
-            Connection conn = Transaction.getStandaloneConnection();
-            if (conn == null) {
-                return "Unable to get anotehr db connection";
-            }
-
-            concierge.reset(conn);
-            return "Done";
-        }
-
-        @Override
-        public String resetKeepAliveTask(int seconds) {
-            if (_executor != null) {
-                try {
-                    _executor.shutdown();
-                } catch(Exception e) {
-                    s_logger.error("Unable to shutdown executor", e);
-                }
-            }
-
-            _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ConnectionConcierge"));
-
-            _executor.scheduleAtFixedRate(new Runnable() {
-
-                @Override
-                public void run() {
-                    s_logger.trace("connection concierge keep alive task");
-                    for (Map.Entry<String, ConnectionConcierge> entry : _conns.entrySet()) {
-                        ConnectionConcierge concierge = entry.getValue();
-                        if (concierge.keepAlive()) {
-                            testValidity(entry.getKey(), entry.getValue().conn());
-                        }
-                    }
-                }
-            }, 0, seconds, TimeUnit.SECONDS);
-
-            return "As you wish.";
-        }
-
-        @Override
-        public List<String> getConnectionsNotPooled() {
-            return new ArrayList<String>(_conns.keySet());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/ConnectionConciergeMBean.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/ConnectionConciergeMBean.java b/utils/src/com/cloud/utils/db/ConnectionConciergeMBean.java
deleted file mode 100644
index 19a09cd..0000000
--- a/utils/src/com/cloud/utils/db/ConnectionConciergeMBean.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.List;
-
-public interface ConnectionConciergeMBean {
-    
-    List<String> testValidityOfConnections();
-    
-    String resetConnection(String name);
-    
-    String resetKeepAliveTask(int seconds);
-    
-    List<String> getConnectionsNotPooled();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/DB.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/DB.java b/utils/src/com/cloud/utils/db/DB.java
deleted file mode 100644
index f83a7ea..0000000
--- a/utils/src/com/cloud/utils/db/DB.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Running with assertions on, will find all classes that are
- * 
- * 1. Annotate method that starts and commits DB transactions.
- *    Transaction txn = Transaction.currentTxn();
- *    txn.start();
- *    ...
- *    txn.commit();
- * 
- * 2. Annotate methods that uses a DAO's acquire method.
- *    _dao.acquireInLockTable(id);
- *    ...
- *    _dao.releaseFromLockTable(id);
- * 
- * 3. Annotate methods that are inside a DAO but doesn't use
- *    the Transaction class.  Generally, these are methods
- *    that are utility methods for setting up searches.  In
- *    this case use @DB(txn=false) to annotate the method.
- *    While this is not required, it helps when you're debugging
- *    the code and it saves on method calls during runtime.
- *
- */
-@Target({TYPE, METHOD})
-@Retention(RUNTIME)
-public @interface DB {
-    /**
-     * (Optional) Specifies that the method
-     * does not use transaction.  This is useful for
-     * utility methods within DAO classes which are
-     * automatically marked with @DB.  By marking txn=false,
-     * the method is not surrounded with transaction code.
-     */
-    boolean txn() default true;
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/DbUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/DbUtil.java b/utils/src/com/cloud/utils/db/DbUtil.java
deleted file mode 100755
index da0efbb..0000000
--- a/utils/src/com/cloud/utils/db/DbUtil.java
+++ /dev/null
@@ -1,342 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.persistence.AttributeOverride;
-import javax.persistence.AttributeOverrides;
-import javax.persistence.Column;
-import javax.persistence.Embeddable;
-import javax.persistence.Embedded;
-import javax.persistence.EmbeddedId;
-import javax.persistence.Id;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.PrimaryKeyJoinColumns;
-import javax.persistence.SecondaryTable;
-import javax.persistence.SecondaryTables;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-import org.apache.log4j.Logger;
-
-public class DbUtil {
-    protected final static Logger s_logger = Logger.getLogger(DbUtil.class);
-    
-    private static Map<String, Connection> s_connectionForGlobalLocks = new HashMap<String, Connection>();
-    
-    public static Connection getConnectionForGlobalLocks(String name, boolean forLock) {
-    	synchronized(s_connectionForGlobalLocks) {
-    		if(forLock) {
-    			if(s_connectionForGlobalLocks.get(name) != null) {
-    				s_logger.error("Sanity check failed, global lock name " + name + " is already in use");
-    				assert(false);
-    			}
-    			
-    			Connection connection = Transaction.getStandaloneConnection();
-    			if(connection != null) {
-    				try {
-						connection.setAutoCommit(true);
-					} catch (SQLException e) {
-						try {
-							connection.close();
-						} catch(SQLException sqlException) {
-						}
-						return null;
-					}
-					s_connectionForGlobalLocks.put(name, connection);
-					return connection;
-    			}
-    	    	return null;
-    		} else {
-    			Connection connection = s_connectionForGlobalLocks.get(name);
-    			s_connectionForGlobalLocks.remove(name);
-    			return connection;
-    		}
-    	}
-    }
-    
-    public static void removeConnectionForGlobalLocks(String name) {
-    	synchronized(s_connectionForGlobalLocks) {
-    		s_connectionForGlobalLocks.remove(name);
-    	}
-    }
-	
-    public static String getColumnName(Field field, AttributeOverride[] overrides) {
-        if (overrides != null) {
-            for (AttributeOverride override : overrides) {
-                if (override.name().equals(field.getName())) {
-                    return override.column().name();
-                }
-            }
-        }
-        
-        assert(field.getAnnotation(Embedded.class) == null) : "Cannot get column name from embedded field: " + field.getName();
-        
-        Column column = field.getAnnotation(Column.class);
-        return column != null ? column.name() : field.getName();
-    }
-    
-    public static String getColumnName(Field field) {
-        return getColumnName(field, null);
-    }
-    
-    public static String getReferenceColumn(PrimaryKeyJoinColumn pkjc) {
-        return pkjc.referencedColumnName().length() != 0
-            ? pkjc.referencedColumnName()
-            : pkjc.name();
-    }
-    
-    public static PrimaryKeyJoinColumn[] getPrimaryKeyJoinColumns(Class<?> clazz) {
-        PrimaryKeyJoinColumn pkjc = clazz.getAnnotation(PrimaryKeyJoinColumn.class);
-        if (pkjc != null) {
-            return new PrimaryKeyJoinColumn[] { pkjc };
-        }
-        
-        PrimaryKeyJoinColumns pkjcs = clazz.getAnnotation(PrimaryKeyJoinColumns.class);
-        if (pkjcs != null) {
-            return pkjcs.value();
-        }
-        
-        return null;
-    }
-    
-    public static Field findField(Class<?> clazz, String columnName) {
-        for (Field field : clazz.getDeclaredFields()) {
-            if (field.getAnnotation(Embedded.class) != null || field.getAnnotation(EmbeddedId.class) != null) {
-                findField(field.getClass(), columnName);
-            } else {
-                if (columnName.equals(DbUtil.getColumnName(field))) {
-                    return field;
-                }
-            }
-        }
-        return null;
-    }
-    
-    public static final AttributeOverride[] getAttributeOverrides(AnnotatedElement ae) {
-        AttributeOverride[] overrides = null;
-        
-        AttributeOverrides aos = ae.getAnnotation(AttributeOverrides.class);
-        if (aos != null) {
-            overrides = aos.value();
-        }
-        
-        if (overrides == null || overrides.length == 0) {
-            AttributeOverride override = ae.getAnnotation(AttributeOverride.class);
-            if (override != null) {
-                overrides = new AttributeOverride[1];
-                overrides[0] = override;
-            } else {
-                overrides = new AttributeOverride[0];
-            }
-        }
-        
-        return overrides;
-    }
-    
-    public static final boolean isPersistable(Field field) {
-        if (field.getAnnotation(Transient.class) != null) {
-            return false;
-        }
-        
-        int modifiers = field.getModifiers();
-        return !(Modifier.isFinal(modifiers) ||
-                 Modifier.isStatic(modifiers) ||
-                 Modifier.isTransient(modifiers));
-    }
-    
-    public static final boolean isIdField(Field field) {
-        if (field.getAnnotation(Id.class) != null) {
-            return true;
-        }
-        
-        if (field.getAnnotation(EmbeddedId.class) != null) {
-            assert (field.getClass().getAnnotation(Embeddable.class) != null) : "Class " + field.getClass().getName() + " must be Embeddable to be used as Embedded Id";
-            return true;
-        }
-        
-        return false;
-    }
-    
-    public static final SecondaryTable[] getSecondaryTables(AnnotatedElement clazz) {
-        SecondaryTable[] sts = null;
-        SecondaryTable stAnnotation = clazz.getAnnotation(SecondaryTable.class);
-        if (stAnnotation == null) {
-            SecondaryTables stsAnnotation = clazz.getAnnotation(SecondaryTables.class);
-            sts = stsAnnotation != null ? stsAnnotation.value() : new SecondaryTable[0];
-        } else {
-            sts = new SecondaryTable[] {stAnnotation};
-        }
-        
-        return sts;
-    }
-    
-    public static final String getTableName(Class<?> clazz) {
-        Table table = clazz.getAnnotation(Table.class);
-        return table != null ? table.name() : clazz.getSimpleName();
-    }
-    
-    public static boolean getGlobalLock(String name, int timeoutSeconds) {
-        Connection conn = getConnectionForGlobalLocks(name, true);
-        if(conn == null) {
-            s_logger.error("Unable to acquire DB connection for global lock system");
-        	return false;
-        }
-        
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = conn.prepareStatement("SELECT COALESCE(GET_LOCK(?, ?),0)");
-
-            pstmt.setString(1, name);
-            pstmt.setInt(2, timeoutSeconds);
-            
-            ResultSet rs = pstmt.executeQuery();
-            if (rs != null && rs.first()) {
-            	 if(rs.getInt(1) > 0) {
-            		 return true;
-            	 } else {
-            		 if(s_logger.isDebugEnabled())
-            			 s_logger.debug("GET_LOCK() timed out on lock : " + name);
-            	 }
-            }
-        } catch (SQLException e) {
-            s_logger.error("GET_LOCK() throws exception ", e);
-        } catch (Throwable e) {
-            s_logger.error("GET_LOCK() throws exception ", e);
-        } finally {
-        	if (pstmt != null) {
-        		try {
-        			pstmt.close();
-        		} catch (Throwable e) {
-        			s_logger.error("What the heck? ", e);
-        		}
-        	}
-        }
-        
-        removeConnectionForGlobalLocks(name);
-        try {
-			conn.close();
-		} catch (SQLException e) {
-		}
-        return false;
-    }
-    
-    
-    public static Class<?> getEntityBeanType(GenericDao<?, Long> dao) {
-        return dao.getEntityBeanType();
-    }
-    
-    public static boolean releaseGlobalLock(String name) {
-        Connection conn = getConnectionForGlobalLocks(name, false);
-        if(conn == null) {
-            s_logger.error("Unable to acquire DB connection for global lock system");
-            assert(false);
-        	return false;
-        }
-        
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = conn.prepareStatement("SELECT COALESCE(RELEASE_LOCK(?), 0)");
-            pstmt.setString(1, name);
-            ResultSet rs = pstmt.executeQuery();
-            if(rs != null && rs.first())
-            	return rs.getInt(1) > 0;
-            s_logger.error("RELEASE_LOCK() returns unexpected result : " + rs.getInt(1));
-        } catch (SQLException e) {
-            s_logger.error("RELEASE_LOCK() throws exception ", e);
-        } catch (Throwable e) {
-            s_logger.error("RELEASE_LOCK() throws exception ", e);
-        } finally {
-        	try {
-            	if (pstmt != null) {
-    	        	pstmt.close();
-            	}
-        		conn.close();
-        	} catch(SQLException e) {
-        	}
-        }
-        return false;
-    }
-
-    public static void closeResources(final Connection connection,
-            final Statement statement, final ResultSet resultSet) {
-
-        closeResultSet(resultSet);
-        closeStatement(statement);
-        closeConnection(connection);
-
-    }
-
-    public static void closeResources(final Statement statement, final ResultSet resultSet) {
-
-        closeResources(null, statement, resultSet);
-
-    }
-    
-    public static void closeResultSet(final ResultSet resultSet) {
-
-        try {
-            
-            if (resultSet != null) {
-                resultSet.close();
-            }
-
-        } catch (Exception e) {
-            s_logger.warn("Ignored exception while closing result set.",e);
-        }
-
-    }
-
-    public static void closeStatement(final Statement statement) {
-
-        try {
-
-            if (statement != null) {
-                statement.close();
-            }
-
-        } catch (Exception e) {
-            s_logger.warn("Ignored exception while closing statement.",e);
-        }
-
-    }
-
-    public static void closeConnection(final Connection connection) {
-
-        try {
-
-            if (connection != null) {
-                connection.close();
-            }
-
-        } catch (Exception e) {
-            s_logger.warn("Ignored exception while close connection.",e);
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/EcInfo.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/EcInfo.java b/utils/src/com/cloud/utils/db/EcInfo.java
deleted file mode 100644
index b33aa57..0000000
--- a/utils/src/com/cloud/utils/db/EcInfo.java
+++ /dev/null
@@ -1,106 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.persistence.CollectionTable;
-import javax.persistence.ElementCollection;
-import javax.persistence.JoinColumn;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class EcInfo {
-    protected String insertSql;
-    protected String selectSql;
-    protected String clearSql;
-    protected Class<?> targetClass;
-    protected Class<?> rawClass;
-
-    public EcInfo(Attribute attr, Attribute idAttr) {
-        attr.attache = this;
-        ElementCollection ec = attr.field.getAnnotation(ElementCollection.class);
-        targetClass = ec.targetClass();
-        Class<?> type = attr.field.getType();
-        if (type.isArray()) {
-            rawClass = null;
-        } else {
-            ParameterizedType pType = (ParameterizedType)attr.field.getGenericType();
-            Type rawType = pType.getRawType();
-            Class<?> rawClazz = (Class<?>)rawType;
-            try {
-                if (!Modifier.isAbstract(rawClazz.getModifiers()) && !rawClazz.isInterface() && rawClazz.getConstructors().length != 0 && rawClazz.getConstructor() != null) {
-                    rawClass = rawClazz;
-                } else if (Set.class == rawClazz) {
-                    rawClass = HashSet.class;
-                } else if (List.class == rawClazz) {
-                    rawClass = ArrayList.class;
-                } else if (Collection.class == Collection.class) {
-                    rawClass = ArrayList.class;
-                } else {
-                    assert (false) : " We don't know how to create this calss " + rawType.toString() + " for " + attr.field.getName();
-                }
-            } catch (NoSuchMethodException e) {
-                throw new CloudRuntimeException("Write your own support for " + rawClazz + " defined by " + attr.field.getName());
-            }
-        }
-
-        CollectionTable ct = attr.field.getAnnotation(CollectionTable.class);
-        assert (ct.name().length() > 0) : "Please sepcify the table for " + attr.field.getName();
-        StringBuilder selectBuf = new StringBuilder("SELECT ");
-        StringBuilder insertBuf = new StringBuilder("INSERT INTO ");
-        StringBuilder clearBuf = new StringBuilder("DELETE FROM ");
-
-        clearBuf.append(ct.name()).append(" WHERE ");
-        selectBuf.append(attr.columnName);
-        selectBuf.append(" FROM ").append(ct.name()).append(", ").append(attr.table);
-        selectBuf.append(" WHERE ");
-
-        insertBuf.append(ct.name()).append("(");
-        StringBuilder valuesBuf = new StringBuilder("SELECT ");
-
-        for (JoinColumn jc : ct.joinColumns()) {
-            selectBuf.append(ct.name()).append(".").append(jc.name()).append("=");
-            if (jc.referencedColumnName().length() == 0) {
-                selectBuf.append(idAttr.table).append(".").append(idAttr.columnName);
-                valuesBuf.append(idAttr.table).append(".").append(idAttr.columnName);
-                clearBuf.append(ct.name()).append(".").append(jc.name()).append("=?");
-            } else {
-                selectBuf.append(attr.table).append(".").append(jc.referencedColumnName());
-                valuesBuf.append(attr.table).append(".").append(jc.referencedColumnName()).append(",");
-            }
-            selectBuf.append(" AND ");
-            insertBuf.append(jc.name()).append(", ");
-            valuesBuf.append(", ");
-        }
-
-        selectSql = selectBuf.append(idAttr.table).append(".").append(idAttr.columnName).append("=?").toString();
-        insertBuf.append(attr.columnName).append(") ");
-        valuesBuf.append("? FROM ").append(attr.table);
-        valuesBuf.append(" WHERE ").append(idAttr.table).append(".").append(idAttr.columnName).append("=?");
-
-        insertSql = insertBuf.append(valuesBuf).toString();
-        clearSql = clearBuf.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/Encrypt.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Encrypt.java b/utils/src/com/cloud/utils/db/Encrypt.java
deleted file mode 100755
index 4973458..0000000
--- a/utils/src/com/cloud/utils/db/Encrypt.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Encrypt is a replacement for the column modification.   
- */
-@Target(FIELD)
-@Retention(RUNTIME)
-public @interface Encrypt {
-    boolean encrypt() default true;
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/EntityManager.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/EntityManager.java b/utils/src/com/cloud/utils/db/EntityManager.java
index 24e12f8..49f4f72 100644
--- a/utils/src/com/cloud/utils/db/EntityManager.java
+++ b/utils/src/com/cloud/utils/db/EntityManager.java
@@ -35,16 +35,6 @@ public interface EntityManager {
     public <T, K extends Serializable> T findById(Class<T> entityType, K id);
 
     /**
-     * Finds an entity by its id including removed.
-     * @param <T> class of the entity you're trying to find.
-     * @param <K> class of the id that the entity uses.
-     * @param entityType Type of the entity.
-     * @param id id value
-     * @return T if found; null if not.
-     */
-    public <T, K extends Serializable> T findByIdIncludingRemoved(Class<T> entityType, K id);
-    
-    /**
      * Finds a unique entity by uuid string
      * @param <T> entity class
      * @param entityType type of entity you're looking for.
@@ -54,15 +44,6 @@ public interface EntityManager {
     public <T> T findByUuid(Class<T> entityType, String uuid);
 
     /**
-     * Finds a unique entity by uuid string
-     * @param <T> entity class
-     * @param entityType type of entity you're looking for.
-     * @param uuid the unique id
-     * @return T if found, null if not.
-     */
-    public <T> T findByUuidIncludingRemoved(Class<T> entityType, String uuid);
-
-    /**
      * Finds an entity by external id which is always String
      * @param <T> entity class
      * @param entityType type of entity you're looking for.
@@ -79,20 +60,6 @@ public interface EntityManager {
      */
     public <T> List<? extends T> list(Class<T> entityType);
 
-    /**
-     * Persists the entity.
-     * @param <T> entity class
-     * @param t entity
-     * @return persisted entity.  Only use this after persisting.
-     */
-    public <T> T persist(T t);
-
-    public <T> SearchBuilder<T> createSearchBuilder(Class<T> entityType);
-
-    public <T, K> GenericSearchBuilder<T, K> createGenericSearchBuilder(Class<T> entityType, Class<K> resultType);
-
-    public <T, K> List<K> search(Class<T> entityType, SearchCriteria<K> sc);
-
     public <T, K extends Serializable> void remove(Class<T> entityType, K id);
 }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/Filter.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Filter.java b/utils/src/com/cloud/utils/db/Filter.java
deleted file mode 100755
index c9a4c8a..0000000
--- a/utils/src/com/cloud/utils/db/Filter.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Field;
-
-import javax.persistence.Column;
-
-import com.cloud.utils.Pair;
-import com.cloud.utils.ReflectUtil;
-
-/**
- *  Try to use static initialization to help you in finding incorrect
- *  field names being passed in early.
- * 
- *  Something like the following:
- *  protected static final Filter s_NameFilter = new Filter(VMInstanceVO, name, true, null, null);
- * 
- *  Filter nameFilter = new Filter(s_nameFilter);
- *
- */
-public class Filter {
-    Long _offset;
-    Long _limit;
-    String _orderBy;
-    
-    /**
-     * @param clazz the VO object type
-     * @param field name of the field
-     * @param offset
-     * @param limit
-     */
-    public Filter(Class<?> clazz, String field, boolean ascending, Long offset, Long limit) {
-        _offset = offset;
-        _limit = limit;
-        
-        addOrderBy(clazz, field, ascending);
-    }
-    
-    public Filter(long limit) {
-        _orderBy = " ORDER BY RAND() LIMIT " + limit;
-    }
-    
-    /**
-     * Note that this copy constructor does not copy offset and limit.
-     * @param that filter
-     */
-    public Filter(Filter that) {
-        this._orderBy = that._orderBy;
-        this._limit = null;
-        that._limit = null;
-    }
-    
-    public void addOrderBy(Class<?> clazz, String field, boolean ascending) {
-        if (field == null) {
-            return;
-        }
-        Field f;
-        Pair<Class<?>, Field> pair = ReflectUtil.getAnyField(clazz, field);
-        assert(pair != null) : "Can't find field " + field + " in " + clazz.getName();
-        clazz = pair.first();
-        f = pair.second();
-        
-        Column column = f.getAnnotation(Column.class);
-        String name = column != null ? column.name() : field;
-        
-        StringBuilder order = new StringBuilder();
-        if (column.table() == null || column.table().length() == 0) {
-            order.append(DbUtil.getTableName(clazz));
-        } else {
-            order.append(column.table());
-        }
-        order.append(".").append(name).append(ascending ? " ASC " : " DESC ");
-        
-        if (_orderBy == null) {
-            _orderBy = order.insert(0, " ORDER BY ").toString();
-        } else {
-            _orderBy = order.insert(0, _orderBy).toString();
-        }
-    }
-    
-    public String getOrderBy() {
-        return _orderBy;
-    }
-    
-    public void setOffset(Long offset) {
-        _offset = offset;
-    }
-    
-    public Long getOffset() {
-        return _offset;
-    }
-    
-    public Long getLimit() {
-        return _limit;
-    }
-    
-    public void setLimit(Long limit) {
-        _limit = limit;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/GenericDao.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java
deleted file mode 100755
index 1c830c8..0000000
--- a/utils/src/com/cloud/utils/db/GenericDao.java
+++ /dev/null
@@ -1,284 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import com.cloud.utils.Pair;
-
-/**
- * a uniform method for persisting and finding db entities.
- **/
-public interface GenericDao<T, ID extends Serializable> {
- 
-    /**
-     */
-    static final String REMOVED_COLUMN = "cloud_removed";
-    
-    static final String REMOVED = "removed";
-    
-    /**
-     * This column can be used if the table wants to track creation time.
-     */
-    static final String CREATED_COLUMN = "created";
-    
-    /**
-     */
-    static final String XID_COLUMN = "xid";
-    
-    /**
-     * Look for an entity bean using the database id.  Does not lock the row.
-     * @param id database unique id for the entity bean.
-     * @return entity bean.
-     **/
-    T findById(ID id);
-    
-    T findByIdIncludingRemoved(ID id);
-    
-    T findById(ID id, boolean fresh);
-
-    // Finds one unique VO using uuid
-    T findByUuid(String uuid);
-
-    // Finds one unique VO using uuid including removed entities
-    T findByUuidIncludingRemoved(String uuid);
-    
-    /**
-     * @return VO object ready to be used for update.  It won't have any fields filled in.
-     */
-    T createForUpdate();
-    
-    SearchBuilder<T> createSearchBuilder();
-    <K> GenericSearchBuilder<T, K> createSearchBuilder(Class<K> clazz);
-    
-    T createForUpdate(ID id);
-    
-    /**
-     * Returns a SearchCriteria object that can be used to build search conditions.
-     * 
-     * @return SearchCriteria
-     */
-    SearchCriteria<T> createSearchCriteria();
-    
-    /**
-     * lock the rows that matched the search criteria and filter.  This method needs
-     * to be called within a transaction.
-     * 
-     * @param sc SearchCriteria containing the different search conditions
-     * @param filter Filter containing limits etc
-     * @param exclusive exclusive or share lock
-     * @return List<T> list of entity beans
-     */
-    List<T> lockRows(SearchCriteria<T> sc, Filter filter, boolean exclusive);
-    
-    /**
-     * lock 1 of the return set.  This method needs to be run within a
-     * transaction or else it's useless.
-     * @param sc
-     * @param exclusive
-     * @return T if found and locked.  null if not.
-     */
-    T lockOneRandomRow(SearchCriteria<T> sc, boolean exclusive);
-    
-    /**
-     * Find and lock the row for update.
-     * @param id id
-     * @param exclusive is this a read share lock or exclusive lock?
-     * @return T
-     */
-    T lockRow(ID id, Boolean exclusive);
-
-    /**
-     * Acquires a database wide lock on the id of the entity.  This ensures
-     * that only one is being used.  The timeout is the configured default.
-     * 
-     * @param id id of the entity to acquire an lock on.
-     * @return object if acquired; null if not.  If null, you need to call findById to see if it is actually not found.
-     */
-    T acquireInLockTable(ID id);
-    
-    /**
-     * Acquires a database wide lock on the id of the entity.  This ensures
-     * that only one is being used.  The timeout is the configured default.
-     * 
-     * @param id id of the entity to acquire an lock on.
-     * @param seconds time to wait for the lock.
-     * @return entity if the lock is acquired; null if not.
-     */
-    T acquireInLockTable(ID id, int seconds);
-    
-    /**
-     * releases the lock acquired in the acquire method call.
-     * @param id id of the entity to release the lock on.
-     * @return true if it is released.  false if not or not found.
-     */
-    boolean releaseFromLockTable(final ID id);
-    
-    boolean update(ID id, T entity);
-    
-    int update(T entity, SearchCriteria<T> sc);
-    
-    /**
-     * Look for all active rows.
-     * @return list of entity beans.
-     */
-    List<T> listAll();
-
-    /**
-     * Look for all active rows.
-     * @param filter filter to limit the results
-     * @return list of entity beans.
-     */
-    List<T> listAll(Filter filter);
-    
-    
-    /**
-     * Search for the entity beans
-     * @param sc
-     * @param filter
-     * @return list of entity beans.
-     */
-    List<T> search(SearchCriteria<T> sc, Filter filter);
-    
-
-    /**
-     * Search for the entity beans using the sql SQL_CACHE option
-     * @param sc
-     * @param filter
-     * @param enable_query_cache
-     * @return list of entity beans.
-     */
-    List<T> search(SearchCriteria<T> sc, Filter filter, final boolean enable_query_cache);
-    
-    
-    List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache);
-    
-
-    List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enable_query_cache);
-    
-    
-    /**
-     * Customized search with SearchCritiria
-     * @param sc
-     * @param filter
-     * @return list of entity beans.
-     */
-    public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, Filter filter);
-    
-    /**
-     * Retrieves the entire table.
-     * @return collection of entity beans.
-     **/
-    List<T> listAllIncludingRemoved();
-
-    /**
-     * Retrieves the entire table.
-     * @param filter filter to limit the returns.
-     * @return collection of entity beans.
-     **/
-    List<T> listAllIncludingRemoved(Filter filter);
-    
-    /**
-     * Persist the entity bean.  The id field of the entity is updated with
-     * the new id.
-     * @param entity the bean to persist.
-     * @return The persisted version of the object.  A null is returned if
-     * there's no primary key specified in the VO object.
-     **/
-    T persist(T entity);
-    
-    /**
-     * remove the entity bean.  This will call delete automatically if
-     * the entity bean does not have a removed field.
-     * @param id
-     * @return true if removed.
-     */
-    boolean remove(ID id);
-    
-    /**
-     * Remove based on the search criteria.  This will delete if the VO object
-     * does not have a REMOVED column. 
-     * @param sc search criteria to match
-     * @return rows removed.
-     */
-    int remove(SearchCriteria<T> sc);
-    
-    /**
-     * Expunge actually delete the row even if it's REMOVED.
-     * @param id
-     * @return true if removed.
-     */
-    boolean expunge(ID id);
-    
-    /**
-     * remove the entity bean specified by the search criteria
-     * @param sc
-     * @return number of rows deleted
-     */
-    int expunge(final SearchCriteria<T> sc);
-    
-    /**
-     * expunge the removed rows.
-     */
-    void expunge();
-    
-    public <K> K getNextInSequence(Class<K> clazz, String name);
-    
-    /**
-     * Configure.
-     * @param name name of the dao.
-     * @param params params if any are specified.
-     * @return true if config is good.  false if not.
-     */
-    boolean configure(String name, Map<String, Object> params) throws ConfigurationException;
-    
-    <M> List<M> customSearch(SearchCriteria<M> sc, Filter filter);
-
-    boolean lockInLockTable(String id);
-
-    boolean lockInLockTable(String id, int seconds);
-
-    boolean unlockFromLockTable(String id);
-
-    public <K> K getRandomlyIncreasingNextInSequence(Class<K> clazz, String name);
-
-    <K> SearchCriteria2 createSearchCriteria2(Class<K> resultType);
-
-    SearchCriteria2 createSearchCriteria2();
-
-    public T findOneBy(final SearchCriteria<T> sc);
-
-    /**
-     * @return
-     */
-    Class<T> getEntityBeanType();
-    
-    public int getRegionId();
-
-    /**
-     * @param sc
-     * @param filter
-     * @return
-     */
-    Pair<List<T>, Integer> searchAndCount(SearchCriteria<T> sc, Filter filter);
-
-    Map<String, Attribute> getAllAttributes();
-}


[02/10] Moved the DB layer code into framework-db and change only the necessary projects to refer to it. Cut down on the dependencies introduced with all the code in utils.

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/SearchCriteriaService.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SearchCriteriaService.java b/utils/src/com/cloud/utils/db/SearchCriteriaService.java
deleted file mode 100755
index 2947255..0000000
--- a/utils/src/com/cloud/utils/db/SearchCriteriaService.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.util.List;
-
-import com.cloud.utils.db.SearchCriteria.Op;
-
-public interface SearchCriteriaService<T, K> {
-	public void selectField(Object... useless);
-	public void addAnd(Object useless, Op op, Object...values);
-	public List<K> list();
-	public T getEntity();
-	public <K> K find();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/SequenceFetcher.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SequenceFetcher.java b/utils/src/com/cloud/utils/db/SequenceFetcher.java
deleted file mode 100644
index 8823552..0000000
--- a/utils/src/com/cloud/utils/db/SequenceFetcher.java
+++ /dev/null
@@ -1,171 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Random;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import javax.persistence.TableGenerator;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.concurrency.NamedThreadFactory;
-
-/**
- * Since Mysql does not have sequence support, we have
- * table retrieval was inside a transaction, the value
- * gets locked until the transaction is over.
- * 
- * allocation size.
- *
- */
-public class SequenceFetcher {
-    private final static Logger s_logger = Logger.getLogger(SequenceFetcher.class);
-    ExecutorService _executors;
-    private final static Random random = new Random();
-    
-    public <T> T getNextSequence(Class<T> clazz, TableGenerator tg) {
-        return getNextSequence(clazz, tg, null, false);
-    }
-    
-    public <T> T getNextSequence(Class<T> clazz, TableGenerator tg, Object key) {
-    	return getNextSequence(clazz, tg, key, false);
-    }
-    
-    public <T> T getRandomNextSequence(Class<T> clazz, TableGenerator tg) {
-        return getNextSequence(clazz, tg, null, true);
-    }
-    
-    public <T> T getNextSequence(Class<T> clazz, TableGenerator tg, Object key, boolean isRandom) {
-        Future<T> future = _executors.submit(new Fetcher<T>(clazz, tg, key, isRandom));
-        try {
-            return future.get();
-        } catch (Exception e) {
-            s_logger.warn("Unable to get sequeunce for " + tg.table() + ":" + tg.pkColumnValue(), e);
-            return null;
-        }
-    }
-    
-    protected SequenceFetcher() {
-        _executors = new ThreadPoolExecutor(100, 100, 120l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(250), new NamedThreadFactory("SequenceFetcher"));
-    }
-
-    protected static final SequenceFetcher s_instance = new SequenceFetcher();
-    public static SequenceFetcher getInstance() {
-        return s_instance;
-    }
-    
-    protected class Fetcher<T> implements Callable<T> {
-        TableGenerator _tg;
-        Class<T> _clazz;
-        Object _key;
-        boolean isRandom = false;
-        
-        protected Fetcher(Class<T> clazz, TableGenerator tg, Object key, boolean isRandom) {
-            _tg = tg;
-            _clazz = clazz;
-            _key = key;
-            this.isRandom = isRandom;
-        }
-        
-        @Override @SuppressWarnings("unchecked")
-        public T call() throws Exception {
-            try {
-                PreparedStatement stmt = null;
-                StringBuilder sql = new StringBuilder("SELECT ");
-                sql.append(_tg.valueColumnName()).append(" FROM ").append(_tg.table());
-                sql.append(" WHERE ").append(_tg.pkColumnName()).append(" = ? FOR UPDATE");
-                
-                Transaction txn = Transaction.open("Sequence");
-                
-                PreparedStatement selectStmt = txn.prepareStatement(sql.toString());
-                if (_key == null) {
-                    selectStmt.setString(1, _tg.pkColumnValue());
-                } else {
-                    selectStmt.setObject(1, _key);
-                }
-
-                sql = new StringBuilder("UPDATE ");
-                sql.append(_tg.table()).append(" SET ").append(_tg.valueColumnName()).append("=").append("?+?");
-                sql.append(" WHERE ").append(_tg.pkColumnName()).append("=?");
-                
-                PreparedStatement updateStmt = txn.prepareStatement(sql.toString());
-                if(isRandom){
-                	updateStmt.setInt(2, random.nextInt(10) + 1);
-                } else {
-                	updateStmt.setInt(2, _tg.allocationSize());
-                }
-                if (_key == null) {
-                    updateStmt.setString(3, _tg.pkColumnValue());
-                } else {
-                    updateStmt.setObject(3, _key);
-                }
-                
-                ResultSet rs = null;
-                try {
-                    txn.start();
-                    
-                    stmt = selectStmt;
-                    rs = stmt.executeQuery();
-                    Object obj = null;
-                    while (rs.next()) {
-                        if (_clazz.isAssignableFrom(Long.class)) {
-                            obj = rs.getLong(1);
-                        } else if (_clazz.isAssignableFrom(Integer.class)) {
-                            obj = rs.getInt(1);
-                        } else {
-                            obj = rs.getObject(1);
-                        }
-                    }
-                    
-                    if (obj == null) {
-                        s_logger.warn("Unable to get a sequence: " + updateStmt.toString());
-                        return null;
-                    }
-                    
-                    updateStmt.setObject(1, obj);
-                    stmt = updateStmt;
-                    int rows = stmt.executeUpdate();
-                    assert rows == 1 : "Come on....how exactly did we update this many rows " + rows + " for " + updateStmt.toString();
-                    txn.commit();
-                    return (T)obj;
-                } catch (SQLException e) {
-                    s_logger.warn("Caught this exception when running: " + (stmt != null ? stmt.toString() : ""), e);
-                } finally {
-                    if (rs != null) {
-                        rs.close();
-                    }
-                    selectStmt.close();
-                    updateStmt.close();
-                    txn.close();
-                }
-            } catch (Exception e) {
-                s_logger.warn("Caught this exception when running.", e);
-            }
-            return null;
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/SqlGenerator.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SqlGenerator.java b/utils/src/com/cloud/utils/db/SqlGenerator.java
deleted file mode 100755
index e48fee5..0000000
--- a/utils/src/com/cloud/utils/db/SqlGenerator.java
+++ /dev/null
@@ -1,669 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.persistence.AttributeOverride;
-import javax.persistence.CollectionTable;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.ElementCollection;
-import javax.persistence.Embeddable;
-import javax.persistence.Embedded;
-import javax.persistence.EmbeddedId;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.SecondaryTable;
-import javax.persistence.TableGenerator;
-
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.db.Attribute.Flag;
-
-public class SqlGenerator {
-    Class<?> _clazz;
-    ArrayList<Attribute> _attributes;
-    ArrayList<Field> _embeddeds;
-    ArrayList<Class<?>> _tables;
-    LinkedHashMap<String, List<Attribute>> _ids;
-    HashMap<String, TableGenerator> _generators;
-    ArrayList<Attribute> _ecAttrs;
-
-    public SqlGenerator(Class<?> clazz) {
-        _clazz = clazz;
-        _tables = new ArrayList<Class<?>>();
-        _attributes = new ArrayList<Attribute>();
-        _ecAttrs = new ArrayList<Attribute>();
-        _embeddeds = new ArrayList<Field>();
-        _ids = new LinkedHashMap<String, List<Attribute>>();
-        _generators = new HashMap<String, TableGenerator>();
-
-        buildAttributes(clazz, DbUtil.getTableName(clazz), DbUtil.getAttributeOverrides(clazz), false, false);
-        assert (_tables.size() > 0) : "Did you forget to put @Entity on " + clazz.getName();
-        handleDaoAttributes(clazz);
-        findEcAttributes();
-    }
-
-    protected boolean checkMethods(Class<?> clazz, Map<String, Attribute> attrs) {
-        Method[] methods = clazz.getMethods();
-        for (Method method : methods) {
-            String name = method.getName();
-            if (name.startsWith("get")) {
-                String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
-                assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
-            } else if (name.startsWith("is")) {
-                String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
-                assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
-            } else if (name.startsWith("set")) {
-                String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
-                assert !attrs.containsKey(fieldName) : "Mismatch in " + clazz.getSimpleName() + " for " + name;
-            }
-        }
-        return true;
-
-    }
-
-    protected void buildAttributes(Class<?> clazz, String tableName, AttributeOverride[] overrides, boolean embedded, boolean isId) {
-        if (!embedded && clazz.getAnnotation(Entity.class) == null) {
-            return;
-        }
-
-        Class<?> parent = clazz.getSuperclass();
-        if (parent != null) {
-            buildAttributes(parent, DbUtil.getTableName(parent), DbUtil.getAttributeOverrides(parent), false, false);
-        }
-
-        if (!embedded) {
-            _tables.add(clazz);
-            _ids.put(tableName, new ArrayList<Attribute>());
-        }
-
-        Field[] fields = clazz.getDeclaredFields();
-        for (Field field : fields) {
-            field.setAccessible(true);
-
-            TableGenerator tg = field.getAnnotation(TableGenerator.class);
-            if (tg != null) {
-                _generators.put(field.getName(), tg);
-            }
-
-            if (!DbUtil.isPersistable(field)) {
-                continue;
-            }
-
-            if (field.getAnnotation(Embedded.class) != null) {
-                _embeddeds.add(field);
-                Class<?> embeddedClass = field.getType();
-                assert (embeddedClass.getAnnotation(Embeddable.class) != null) : "Class is not annotated with Embeddable: " + embeddedClass.getName();
-                buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, false);
-                continue;
-            }
-
-            if (field.getAnnotation(EmbeddedId.class) != null) {
-                _embeddeds.add(field);
-                Class<?> embeddedClass = field.getType();
-                assert (embeddedClass.getAnnotation(Embeddable.class) != null) : "Class is not annotated with Embeddable: " + embeddedClass.getName();
-                buildAttributes(embeddedClass, tableName, DbUtil.getAttributeOverrides(field), true, true);
-                continue;
-            }
-
-            Attribute attr = new Attribute(clazz, overrides, field, tableName, embedded, isId);
-
-            if (attr.getColumnName().equals(GenericDao.REMOVED_COLUMN)) {
-                attr.setColumnName(GenericDao.REMOVED);
-                attr.setTrue(Attribute.Flag.DaoGenerated);
-                attr.setFalse(Attribute.Flag.Insertable);
-                attr.setFalse(Attribute.Flag.Updatable);
-                attr.setTrue(Attribute.Flag.TimeStamp);
-                attr.setFalse(Attribute.Flag.Time);
-                attr.setFalse(Attribute.Flag.Date);
-                attr.setTrue(Attribute.Flag.Nullable);
-                attr.setTrue(Attribute.Flag.Removed);
-            } 
-
-            if (attr.isId()) {
-                List<Attribute> attrs = _ids.get(tableName);
-                attrs.add(attr);
-            }
-
-            _attributes.add(attr);
-        }
-    }
-
-    protected void findEcAttributes() {
-        for (Attribute attr : _attributes) {
-            if (attr.field == null) {
-                continue;
-            }
-            ElementCollection ec = attr.field.getAnnotation(ElementCollection.class);
-            if (ec != null) {
-                Attribute idAttr = _ids.get(attr.table).get(0);
-                assert supportsElementCollection(attr.field) : "Doesn't support ElementCollection for " + attr.field.getName();
-                attr.attache = new EcInfo(attr, idAttr);
-                _ecAttrs.add(attr);
-            }
-        }
-    }
-
-    protected boolean supportsElementCollection(Field field) {
-        ElementCollection otm = field.getAnnotation(ElementCollection.class);
-        if (otm.fetch() == FetchType.LAZY) {
-            assert (false) : "Doesn't support laz fetch: " + field.getName();
-            return false;
-        }
-
-        CollectionTable ct = field.getAnnotation(CollectionTable.class);
-        if (ct == null) {
-            assert (false) : "No collection table sepcified for " + field.getName();
-            return false;
-        }
-
-        return true;
-    }
-
-    public Map<String, TableGenerator> getTableGenerators() {
-        return _generators;
-    }
-
-    protected void handleDaoAttributes(Class<?> clazz) {
-        Attribute attr;
-        Class<?> current = clazz;
-        while (current != null && current.getAnnotation(Entity.class) != null) {
-            DiscriminatorColumn column = current.getAnnotation(DiscriminatorColumn.class);
-            if (column != null) {
-                String columnName = column.name();
-                attr = findAttribute(columnName);
-                if (attr != null) {
-                    attr.setTrue(Attribute.Flag.DaoGenerated);
-                    attr.setTrue(Attribute.Flag.Insertable);
-                    attr.setTrue(Attribute.Flag.Updatable);
-                    attr.setFalse(Attribute.Flag.Nullable);
-                    attr.setTrue(Attribute.Flag.DC);
-                } else {
-                    attr = new Attribute(DbUtil.getTableName(current), column.name());
-                    attr.setFalse(Flag.Selectable);
-                    attr.setTrue(Flag.Insertable);
-                    attr.setTrue(Flag.DaoGenerated);
-                    attr.setTrue(Flag.DC);
-                    _attributes.add(attr);
-                }
-                if (column.discriminatorType() == DiscriminatorType.CHAR) {
-                    attr.setTrue(Attribute.Flag.CharDT);
-                } else if (column.discriminatorType() == DiscriminatorType.STRING) {
-                    attr.setTrue(Attribute.Flag.StringDT);
-                } else if (column.discriminatorType() == DiscriminatorType.INTEGER) {
-                    attr.setTrue(Attribute.Flag.IntegerDT);
-                }
-            }
-
-            PrimaryKeyJoinColumn[] pkjcs = DbUtil.getPrimaryKeyJoinColumns(current);
-            if (pkjcs != null) {
-                for (PrimaryKeyJoinColumn pkjc : pkjcs) {
-                    String tableName = DbUtil.getTableName(current);
-                    attr = findAttribute(pkjc.name());
-                    if (attr == null || !tableName.equals(attr.table)) {
-                        Attribute id = new Attribute(DbUtil.getTableName(current), pkjc.name());
-                        if (pkjc.referencedColumnName().length() > 0) {
-                            attr = findAttribute(pkjc.referencedColumnName());
-                            assert (attr != null) : "Couldn't find referenced column name " + pkjc.referencedColumnName();
-                        }
-                        id.field = attr.field;
-                        id.setTrue(Flag.Id);
-                        id.setTrue(Flag.Insertable);
-                        id.setFalse(Flag.Updatable);
-                        id.setFalse(Flag.Nullable);
-                        id.setFalse(Flag.Selectable);
-                        _attributes.add(id);
-                        List<Attribute> attrs = _ids.get(id.table);
-                        attrs.add(id);
-                    }
-                }
-            }
-            current = current.getSuperclass();
-        }
-
-        attr = findAttribute(GenericDao.CREATED_COLUMN);
-        if (attr != null && attr.field.getType() == Date.class) {
-            attr.setTrue(Attribute.Flag.DaoGenerated);
-            attr.setTrue(Attribute.Flag.Insertable);
-            attr.setFalse(Attribute.Flag.Updatable);
-            attr.setFalse(Attribute.Flag.Date);
-            attr.setFalse(Attribute.Flag.Time);
-            attr.setTrue(Attribute.Flag.TimeStamp);
-            attr.setFalse(Attribute.Flag.Nullable);
-            attr.setTrue(Attribute.Flag.Created);
-        }
-
-        attr = findAttribute(GenericDao.XID_COLUMN);
-        if (attr != null && attr.field.getType() == String.class) {
-            attr.setTrue(Attribute.Flag.DaoGenerated);
-            attr.setTrue(Attribute.Flag.Insertable);
-            attr.setFalse(Attribute.Flag.Updatable);
-            attr.setFalse(Attribute.Flag.TimeStamp);
-            attr.setFalse(Attribute.Flag.Time);
-            attr.setFalse(Attribute.Flag.Date);
-            attr.setFalse(Attribute.Flag.Nullable);
-            attr.setFalse(Attribute.Flag.Removed);
-        }
-    }
-
-    public List<Attribute> getElementCollectionAttributes() {
-        return _ecAttrs;
-    }
-
-    public Attribute findAttribute(String name) {
-        for (Attribute attr : _attributes) {
-
-            if (attr.columnName.equalsIgnoreCase(name)) {
-                if (attr.columnName.equalsIgnoreCase(GenericDao.REMOVED) && attr.isUpdatable()) {
-                    return null;
-                }
-                return attr;
-            }
-        }
-
-        return null;
-    }
-
-    public static StringBuilder buildUpdateSql(String tableName, List<Attribute> attrs) {
-        StringBuilder sql = new StringBuilder("UPDATE ");
-        sql.append(tableName).append(" SET ");
-        for (Attribute attr : attrs) {
-            sql.append(attr.columnName).append(" = ?, ");
-        }
-        sql.delete(sql.length() - 2, sql.length());
-        sql.append(" WHERE ");
-
-        return sql;
-    }
-
-    public List<Pair<StringBuilder, Attribute[]>> buildUpdateSqls() {
-        ArrayList<Pair<StringBuilder, Attribute[]>> sqls = new ArrayList<Pair<StringBuilder, Attribute[]>>(_tables.size());
-        for (Class<?> table : _tables) {
-            ArrayList<Attribute> attrs = new ArrayList<Attribute>();
-            String tableName = DbUtil.getTableName(table);
-            for (Attribute attr : _attributes) {
-                if (attr.isUpdatable() && tableName.equals(attr.table)) {
-                    attrs.add(attr);
-                }
-            }
-            if (attrs.size() != 0) {
-                Pair<StringBuilder, Attribute[]> pair =
-                        new Pair<StringBuilder, Attribute[]>(buildUpdateSql(tableName, attrs), attrs.toArray(new Attribute[attrs.size()]));
-                        sqls.add(pair);
-            }
-        }
-        return sqls;
-    }
-
-    public static StringBuilder buildMysqlUpdateSql(String joins, Collection<Ternary<Attribute, Boolean, Object>> setters) {
-        if (setters.size() == 0) {
-            return null;
-        }
-
-        StringBuilder sql = new StringBuilder("UPDATE ");
-
-        sql.append(joins);
-
-        sql.append(" SET ");
-
-        for (Ternary<Attribute, Boolean, Object> setter : setters) {
-            Attribute attr = setter.first();
-            sql.append(attr.table).append(".").append(attr.columnName).append("=");
-            if (setter.second() != null) {
-                sql.append(attr.table).append(".").append(attr.columnName).append(setter.second() ? "+" : "-");
-            }
-            sql.append("?, ");
-        }
-
-        sql.delete(sql.length() - 2, sql.length());
-
-        sql.append(" WHERE ");
-
-        return sql;
-    }
-
-    public List<Pair<String, Attribute[]>> buildInsertSqls() {
-        LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>();
-        for (Class<?> table : _tables) {
-            map.put(DbUtil.getTableName(table), new ArrayList<Attribute>());
-        }
-
-        for (Attribute attr : _attributes) {
-            if (attr.isInsertable()) {
-                ArrayList<Attribute> attrs = map.get(attr.table);
-                assert (attrs != null) : "Null set of attributes for " + attr.table;
-                attrs.add(attr);
-            }
-        }
-
-        List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size());
-        for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) {
-            ArrayList<Attribute> attrs = entry.getValue();
-            StringBuilder sql = buildInsertSql(entry.getKey(), attrs);
-            Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql.toString(), attrs.toArray(new Attribute[attrs.size()]));
-            sqls.add(pair);
-        }
-
-        return sqls;
-    }
-
-    protected StringBuilder buildInsertSql(String table, ArrayList<Attribute> attrs) {
-        StringBuilder sql = new StringBuilder("INSERT INTO ");
-        sql.append(table).append(" (");
-        for (Attribute attr : attrs) {
-            sql.append(table).append(".").append(attr.columnName).append(", ");
-        }
-        if (attrs.size() > 0) {
-            sql.delete(sql.length() - 2, sql.length());
-        }
-
-        sql.append(") VALUES (");
-        for (Attribute attr : attrs) {
-            sql.append("?, ");
-        }
-
-        if (attrs.size() > 0) {
-            sql.delete(sql.length() - 2, sql.length());
-        }
-
-        sql.append(")");
-
-        return sql;
-    }
-
-    protected List<Pair<String, Attribute[]>> buildDeleteSqls() {
-        LinkedHashMap<String, ArrayList<Attribute>> map = new LinkedHashMap<String, ArrayList<Attribute>>();
-        for (Class<?> table : _tables) {
-            map.put(DbUtil.getTableName(table), new ArrayList<Attribute>());
-        }
-
-        for (Attribute attr : _attributes) {
-            if (attr.isId()) {
-                ArrayList<Attribute> attrs = map.get(attr.table);
-                assert (attrs != null) : "Null set of attributes for " + attr.table;
-                attrs.add(attr);
-            }
-        }
-
-        List<Pair<String, Attribute[]>> sqls = new ArrayList<Pair<String, Attribute[]>>(map.size());
-        for (Map.Entry<String, ArrayList<Attribute>> entry : map.entrySet()) {
-            ArrayList<Attribute> attrs = entry.getValue();
-            String sql = buildDeleteSql(entry.getKey(), attrs);
-            Pair<String, Attribute[]> pair = new Pair<String, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()]));
-            sqls.add(pair);
-        }
-
-        Collections.reverse(sqls);
-        return sqls;
-    }
-
-    protected String buildDeleteSql(String table, ArrayList<Attribute> attrs) {
-        StringBuilder sql = new StringBuilder("DELETE FROM ");
-        sql.append(table).append(" WHERE ");
-        for (Attribute attr : attrs) {
-            sql.append(table).append(".").append(attr.columnName).append("= ? AND ");
-        }
-        sql.delete(sql.length() - 5, sql.length());
-        return sql.toString();
-    }
-
-    public Pair<String, Attribute[]> buildRemoveSql() {
-        Attribute attribute = findAttribute(GenericDao.REMOVED);
-        if (attribute == null) {
-            return null;
-        }
-
-        StringBuilder sql = new StringBuilder("UPDATE ");
-        sql.append(attribute.table).append(" SET ");
-        sql.append(attribute.columnName).append(" = ? WHERE ");
-
-        List<Attribute> ids = _ids.get(attribute.table);
-
-        // if ids == null, that means the removed column was added as a JOIN
-        // value to another table.  We ignore it here.
-        if (ids == null) {
-            return null;
-        }
-        if (ids.size() == 0) {
-            return null;
-        }
-
-        for (Attribute id : ids) {
-            sql.append(id.table).append(".").append(id.columnName).append(" = ? AND ");
-        }
-
-        sql.delete(sql.length() - 5, sql.length());
-
-        Attribute[] attrs = ids.toArray(new Attribute[ids.size() + 1]);
-        attrs[attrs.length - 1] = attribute;
-
-        return new Pair<String, Attribute[]>(sql.toString(), attrs);
-    }
-
-    public Map<String, Attribute[]> getIdAttributes() {
-        LinkedHashMap<String, Attribute[]> ids = new LinkedHashMap<String, Attribute[]>(_ids.size());
-
-        for (Map.Entry<String, List<Attribute>> entry : _ids.entrySet()) {
-            ids.put(entry.getKey(), entry.getValue().toArray(new Attribute[entry.getValue().size()]));
-        }
-
-        return ids;
-    }
-
-    /**
-     * @return a map of tables and maps of field names to attributes.
-     */
-    public Map<String, Attribute> getAllAttributes() {
-        Map<String, Attribute> attrs = new LinkedHashMap<String, Attribute>(_attributes.size());
-        for (Attribute attr : _attributes) {
-            if (attr.field != null) {
-                attrs.put(attr.field.getName(), attr);
-            }
-        }
-
-        return attrs;
-    }
-
-    public Map<Pair<String, String>, Attribute> getAllColumns() {
-        Map<Pair<String, String>, Attribute> attrs = new LinkedHashMap<Pair<String, String>, Attribute>(_attributes.size());
-        for (Attribute attr : _attributes) {
-            if (attr.columnName != null) {
-                attrs.put(new Pair<String, String>(attr.table, attr.columnName), attr);
-            }
-        }
-
-        return attrs;
-    }
-
-    protected static void addPrimaryKeyJoinColumns(StringBuilder sql, String fromTable, String toTable, String joinType, PrimaryKeyJoinColumn[] pkjcs) {
-        if ("right".equalsIgnoreCase(joinType)) {
-            sql.append(" RIGHT JOIN ").append(toTable).append(" ON ");
-        } else if ("left".equalsIgnoreCase(joinType)) {
-            sql.append(" LEFT JOIN ").append(toTable).append(" ON ");
-        } else {
-            sql.append(" INNER JOIN ").append(toTable).append(" ON ");
-        }
-        for (PrimaryKeyJoinColumn pkjc : pkjcs) {
-            sql.append(fromTable).append(".").append(pkjc.name());
-            String refColumn = DbUtil.getReferenceColumn(pkjc);
-            sql.append("=").append(toTable).append(".").append(refColumn).append(" ");
-        }
-    }
-
-    public Pair<String, Attribute> getRemovedAttribute() {
-        Attribute removed = findAttribute(GenericDao.REMOVED);
-        if (removed == null) {
-            return null;
-        }
-
-        if (removed.field.getType() != Date.class) {
-            return null;
-        }
-
-        StringBuilder sql = new StringBuilder();
-        sql.append(removed.table).append(".").append(removed.columnName).append(" IS NULL ");
-
-        return new Pair<String, Attribute>(sql.toString(), removed);
-    }
-
-    protected static void buildJoins(StringBuilder innerJoin, Class<?> clazz) {
-        String tableName = DbUtil.getTableName(clazz);
-
-        SecondaryTable[] sts = DbUtil.getSecondaryTables(clazz);
-        ArrayList<String> secondaryTables = new ArrayList<String>();
-        for (SecondaryTable st : sts) {
-            JoinType jt = clazz.getAnnotation(JoinType.class);
-            String join = null;
-            if (jt != null) {
-                join = jt.type();
-            }
-            addPrimaryKeyJoinColumns(innerJoin, tableName, st.name(), join, st.pkJoinColumns());
-            secondaryTables.add(st.name());
-        }
-
-        Class<?> parent = clazz.getSuperclass();
-        if (parent.getAnnotation(Entity.class) != null) {
-            String table = DbUtil.getTableName(parent);
-            PrimaryKeyJoinColumn[] pkjcs = DbUtil.getPrimaryKeyJoinColumns(clazz);
-            assert (pkjcs != null) : "No Join columns specified for the super class";
-            addPrimaryKeyJoinColumns(innerJoin, tableName, table, null, pkjcs);
-        }
-    }
-
-
-    public String buildTableReferences() {
-        StringBuilder sql = new StringBuilder();
-        sql.append(DbUtil.getTableName(_tables.get(_tables.size() - 1)));
-
-        for (Class<?> table : _tables) {
-            buildJoins(sql, table);
-        }
-
-        return sql.toString();
-    }
-
-    public Pair<StringBuilder, Attribute[]> buildSelectSql(boolean enable_query_cache) {
-        StringBuilder sql = new StringBuilder("SELECT ");
-
-        sql.append(enable_query_cache ? "SQL_CACHE ": "");
-
-        ArrayList<Attribute> attrs = new ArrayList<Attribute>();
-
-        for (Attribute attr : _attributes) {
-            if (attr.isSelectable()) {
-                attrs.add(attr);
-                sql.append(attr.table).append(".").append(attr.columnName).append(", ");
-            }
-        }
-
-        if (attrs.size() > 0) {
-            sql.delete(sql.length() - 2, sql.length());
-        }
-
-        sql.append(" FROM ").append(buildTableReferences());
-
-        sql.append(" WHERE ");
-
-        sql.append(buildDiscriminatorClause().first());
-
-        return new Pair<StringBuilder, Attribute[]>(sql, attrs.toArray(new Attribute[attrs.size()]));
-    }
-
-    public Pair<StringBuilder, Attribute[]> buildSelectSql(Attribute[] attrs) {
-        StringBuilder sql = new StringBuilder("SELECT ");
-
-        for (Attribute attr : attrs) {
-            sql.append(attr.table).append(".").append(attr.columnName).append(", ");
-        }
-
-        if (attrs.length > 0) {
-            sql.delete(sql.length() - 2, sql.length());
-        }
-
-        sql.append(" FROM ").append(buildTableReferences());
-
-        sql.append(" WHERE ");
-
-        sql.append(buildDiscriminatorClause().first());
-
-        return new Pair<StringBuilder, Attribute[]>(sql, attrs);
-    }
-
-    /**
-     * buildDiscriminatorClause builds the join clause when there are multiple tables.
-     * 
-     * @return
-     */
-    public Pair<StringBuilder, Map<String, Object>> buildDiscriminatorClause() {
-        StringBuilder sql = new StringBuilder();
-        Map<String, Object> values = new HashMap<String, Object>();
-
-        for (Class<?> table : _tables) {
-            DiscriminatorValue dv = table.getAnnotation(DiscriminatorValue.class);
-            if (dv != null) {
-                Class<?> parent = table.getSuperclass();
-                String tableName = DbUtil.getTableName(parent);
-                DiscriminatorColumn dc = parent.getAnnotation(DiscriminatorColumn.class);
-                assert(dc != null) : "Parent does not have discrminator column: " + parent.getName();
-                sql.append(tableName);
-                sql.append(".");
-                sql.append(dc.name()).append("=");
-                Object value = null;
-                if (dc.discriminatorType() == DiscriminatorType.INTEGER) {
-                    sql.append(dv.value());
-                    value = Integer.parseInt(dv.value());
-                } else if (dc.discriminatorType() == DiscriminatorType.CHAR) {
-                    sql.append(dv.value());
-                    value = dv.value().charAt(0);
-                } else if (dc.discriminatorType() == DiscriminatorType.STRING) {
-                    String v = dv.value();
-                    v = v.substring(0, v.length() < dc.length() ? v.length() : dc.length());
-                    sql.append("'").append(v).append("'");
-                    value = v;
-                }
-                values.put(dc.name(), value);
-                sql.append(" AND ");
-            }
-        }
-
-        return new Pair<StringBuilder, Map<String, Object>>(sql, values);
-    }
-
-    public Field[] getEmbeddedFields() {
-        return _embeddeds.toArray(new Field[_embeddeds.size()]);
-    }
-
-    public String buildCountSql() {
-        StringBuilder sql = new StringBuilder();
-
-        return sql.append("SELECT COUNT(*) FROM ").append(buildTableReferences()).
-                append(" WHERE ").append(buildDiscriminatorClause().first()).toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/StateMachine.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/StateMachine.java b/utils/src/com/cloud/utils/db/StateMachine.java
deleted file mode 100644
index a667d9b..0000000
--- a/utils/src/com/cloud/utils/db/StateMachine.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Target(FIELD)
-@Retention(RUNTIME)
-public @interface StateMachine {
-    public Class<?> state();
-    public Class<?> event();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/Transaction.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/Transaction.java b/utils/src/com/cloud/utils/db/Transaction.java
deleted file mode 100755
index 37ea8cf..0000000
--- a/utils/src/com/cloud/utils/db/Transaction.java
+++ /dev/null
@@ -1,1174 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.sql.DataSource;
-
-import org.apache.commons.dbcp.ConnectionFactory;
-import org.apache.commons.dbcp.DriverManagerConnectionFactory;
-import org.apache.commons.dbcp.PoolableConnectionFactory;
-import org.apache.commons.dbcp.PoolingDataSource;
-import org.apache.commons.pool.KeyedObjectPoolFactory;
-import org.apache.commons.pool.impl.GenericObjectPool;
-import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory;
-import org.apache.log4j.Logger;
-import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
-import org.jasypt.properties.EncryptableProperties;
-
-import com.cloud.utils.Pair;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.crypt.EncryptionSecretKeyChecker;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.mgmt.JmxUtil;
-
-/**
- * Transaction abstracts away the Connection object in JDBC.  It allows the
- * following things that the Connection object does not.
- * 
- *   1. Transaction can be started at an entry point and whether the DB
- *      actions should be auto-commit or not determined at that point.
- *   2. DB Connection is allocated only when it is needed.
- *   3. Code does not need to know if a transaction has been started or not.
- *      It just starts/ends a transaction and we resolve it correctly with
- *      the previous actions.
- *
- * Note that this class is not synchronous but it doesn't need to be because
- * it is stored with TLS and is one per thread.  Use appropriately.
- */
-public class Transaction {
-    private static final Logger s_logger = Logger.getLogger(Transaction.class.getName() + "." + "Transaction");
-    private static final Logger s_stmtLogger = Logger.getLogger(Transaction.class.getName() + "." + "Statement");
-    private static final Logger s_lockLogger = Logger.getLogger(Transaction.class.getName() + "." + "Lock");
-    private static final Logger s_connLogger = Logger.getLogger(Transaction.class.getName() + "." + "Connection");
-
-    private static final ThreadLocal<Transaction> tls = new ThreadLocal<Transaction>();
-    private static final String START_TXN = "start_txn";
-    private static final String CURRENT_TXN = "current_txn";
-    private static final String CREATE_TXN = "create_txn";
-    private static final String CREATE_CONN = "create_conn";
-    private static final String STATEMENT = "statement";
-    private static final String ATTACHMENT = "attachment";
-
-    public static final short CLOUD_DB = 0;
-    public static final short USAGE_DB = 1;
-    public static final short AWSAPI_DB = 2;
-    public static final short SIMULATOR_DB = 3;
-    public static final short CONNECTED_DB = -1;
-    public static int s_region_id;
-
-    private static AtomicLong s_id = new AtomicLong();
-    private static final TransactionMBeanImpl s_mbean = new TransactionMBeanImpl();
-    static {
-        try {
-            JmxUtil.registerMBean("Transaction", "Transaction", s_mbean);
-        } catch (Exception e) {
-            s_logger.error("Unable to register mbean for transaction", e);
-        }
-        
-        /* FIXME: We need a better solution for this
-         * Initialize encryption if we need it for db.properties
-         */ 
-        EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker();
-        enc.check();  
-    }
-
-    private final LinkedList<StackElement> _stack;
-    private long _id;
-
-    private final LinkedList<Pair<String, Long>> _lockTimes = new LinkedList<Pair<String, Long>>();
-
-    private String _name;
-    private Connection _conn;
-    private boolean _txn;
-    private short _dbId;
-    private long _txnTime;
-    private Statement _stmt;
-    private String _creator;
-
-    private Transaction _prev = null;
-
-    public static Transaction currentTxn() {
-        Transaction txn = tls.get();
-        assert txn != null : "No Transaction on stack.  Did you mark the method with @DB?";
-
-        assert checkAnnotation(3, txn) : "Did you even read the guide to use Transaction...IOW...other people's code? Try method can't be private.  What about @DB? hmmm... could that be it? " + txn;
-        return txn;
-    }
-
-    public static Transaction open(final short databaseId) {
-        String name = buildName();
-        if (name == null) {
-            name = CURRENT_TXN;
-        }
-        return open(name, databaseId, true);
-    }
-
-    //
-    // Usage of this transaction setup should be limited, it will always open a new transaction context regardless of whether or not there is other
-    // transaction context in the stack. It is used in special use cases that we want to control DB connection explicitly and in the mean time utilize
-    // the existing DAO features
-    //
-    public void transitToUserManagedConnection(Connection conn) {
-        assert(_conn == null /*&& _stack.size() <= 1*/) : "Can't change to a user managed connection unless the stack is empty and the db connection is null, you may have forgotten to invoke transitToAutoManagedConnection to close out the DB connection: " + toString();
-        _conn = conn;
-        _dbId = CONNECTED_DB;
-    }
-
-    public void transitToAutoManagedConnection(short dbId) {
-        // assert(_stack.size() <= 1) : "Can't change to auto managed connection unless your stack is empty";
-        _dbId = dbId;
-        _conn = null;
-    }
-
-    public static Transaction open(final String name) {
-        return open(name, CLOUD_DB, false);
-    }
-
-    public static Transaction open(final String name, final short databaseId, final boolean forceDbChange) {
-        Transaction txn = tls.get();
-        boolean isNew = false;
-        if (txn == null) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Creating the transaction: " + name);
-            }
-            txn = new Transaction(name, false, databaseId);
-            tls.set(txn);
-            isNew = true;
-        } else if (forceDbChange) {
-            final short currentDbId = txn.getDatabaseId();
-            if (currentDbId != databaseId) {
-                // we need to end the current transaction and switch databases
-                txn.close(txn.getName());
-
-                txn = new Transaction(name, false, databaseId);
-                tls.set(txn);
-                isNew = true;
-            }
-        }
-
-        txn.takeOver(name, false);
-        if (isNew) {
-            s_mbean.addTransaction(txn);
-        }
-        return txn;
-    }
-
-    protected StackElement peekInStack(Object obj) {
-        final Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement next = it.next();
-            if (next.type == obj) {
-                return next;
-            }
-        }
-        return null;
-    }
-
-    public void registerLock(String sql) {
-        if (_txn && s_lockLogger.isDebugEnabled()) {
-            Pair<String, Long> time = new Pair<String, Long>(sql, System.currentTimeMillis());
-            _lockTimes.add(time);
-        }
-    }
-
-    public boolean dbTxnStarted() {
-        return _txn;
-    }
-
-    public static Connection getStandaloneConnectionWithException() throws SQLException {
-        Connection conn = s_ds.getConnection();
-        if (s_connLogger.isTraceEnabled()) {
-            s_connLogger.trace("Retrieving a standalone connection: dbconn" + System.identityHashCode(conn));
-        }
-        return conn;
-    }
-
-    public static Connection getStandaloneConnection() {
-        try {
-            return getStandaloneConnectionWithException();
-        } catch (SQLException e) {
-            s_logger.error("Unexpected exception: ", e);
-            return null;
-        }
-    }
-
-    public static Connection getStandaloneUsageConnection() {
-        try {
-            Connection conn = s_usageDS.getConnection();
-            if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn));
-            }
-            return conn;
-        } catch (SQLException e) {
-            s_logger.warn("Unexpected exception: ", e);
-            return null;
-        }
-    }
-
-    public static Connection getStandaloneAwsapiConnection() {
-        try {
-            Connection conn = s_awsapiDS.getConnection();
-            if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Retrieving a standalone connection for usage: dbconn" + System.identityHashCode(conn));
-            }
-            return conn;
-        } catch (SQLException e) {
-            s_logger.warn("Unexpected exception: ", e);
-            return null;
-        }
-    }
-    
-    public static Connection getStandaloneSimulatorConnection() {
-    	try {
-    		Connection conn = s_simulatorDS.getConnection();
-    		if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Retrieving a standalone connection for simulator: dbconn" + System.identityHashCode(conn));
-            }
-            return conn;
-        } catch (SQLException e) {
-            s_logger.warn("Unexpected exception: ", e);
-            return null;
-        }
-    }
-
-    protected void attach(TransactionAttachment value) {
-        _stack.push(new StackElement(ATTACHMENT, value));
-    }
-
-    protected TransactionAttachment detach(String name) {
-        Iterator<StackElement> it = _stack.descendingIterator();
-        while (it.hasNext()) {
-            StackElement element = it.next();
-            if (element.type == ATTACHMENT) {
-                TransactionAttachment att = (TransactionAttachment)element.ref;
-                if (name.equals(att.getName())) {
-                    it.remove();
-                    return att;
-                }
-            }
-        }
-        assert false : "Are you sure you attached this: " + name;
-        return null;
-    }
-
-    public static void attachToTxn(TransactionAttachment value) {
-        Transaction txn = tls.get();
-        assert txn != null && txn.peekInStack(CURRENT_TXN) != null: "Come on....how can we attach something to the transaction if you haven't started it?";
-
-        txn.attach(value);
-    }
-
-    public static TransactionAttachment detachFromTxn(String name) {
-        Transaction txn = tls.get();
-        assert txn != null : "No Transaction in TLS";
-        return txn.detach(name);
-    }
-
-    protected static boolean checkAnnotation(int stack, Transaction txn) {
-        final StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
-        StackElement se = txn.peekInStack(CURRENT_TXN);
-        if (se == null) {
-            return false;
-        }
-        for (; stack < stacks.length; stack++) {
-            String methodName = stacks[stack].getMethodName();
-            if (methodName.equals(se.ref)){
-                return true;
-            }
-        }
-        return false;
-    }
-
-    protected static String buildName() {
-        if (s_logger.isDebugEnabled()) {
-            final StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
-            final StringBuilder str = new StringBuilder();
-            int i = 3, j = 3;
-            while (j < 15 && i < stacks.length) {
-                StackTraceElement element = stacks[i];
-                String filename = element.getFileName();
-                String method = element.getMethodName();
-                if ((filename != null && filename.equals("<generated>")) || (method != null && method.equals("invokeSuper"))) {
-                    i++;
-                    continue;
-                }
-
-                str.append("-").append(stacks[i].getClassName().substring(stacks[i].getClassName().lastIndexOf(".") + 1)).append(".").append(stacks[i].getMethodName()).append(":").append(stacks[i].getLineNumber());
-                j++;
-                i++;
-            }
-            return str.toString();
-        }
-
-        return "";
-    }
-
-    public Transaction(final String name, final boolean forLocking, final short databaseId) {
-        _name = name;
-        _conn = null;
-        _stack = new LinkedList<StackElement>();
-        _txn = false;
-        _dbId = databaseId;
-        _id = s_id.incrementAndGet();
-        _creator = Thread.currentThread().getName();
-    }
-
-    public String getCreator() {
-        return _creator;
-    }
-
-    public long getId() {
-        return _id;
-    }
-
-    public String getName() {
-        return _name;
-    }
-
-    public Short getDatabaseId() {
-        return _dbId;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder str = new StringBuilder((_name != null ? _name : ""));
-        str.append(" : ");
-        for (final StackElement se : _stack) {
-            if (se.type == CURRENT_TXN) {
-                str.append(se.ref).append(", ");
-            }
-        }
-
-        return str.toString();
-    }
-
-    protected void mark(final String name) {
-        _stack.push(new StackElement(CURRENT_TXN, name));
-    }
-
-    public boolean lock(final String name, final int timeoutSeconds) {
-        Merovingian2 lockMaster = Merovingian2.getLockMaster();
-        if (lockMaster == null) {
-            throw new CloudRuntimeException("There's no support for locking yet");
-        }
-        return lockMaster.acquire(name, timeoutSeconds);
-    }
-
-    public boolean release(final String name) {
-        Merovingian2 lockMaster = Merovingian2.getLockMaster();
-        if (lockMaster == null) {
-            throw new CloudRuntimeException("There's no support for locking yet");
-        }
-        return lockMaster.release(name);
-    }
-
-    public void start() {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("txn: start requested by: " + buildName());
-        }
-
-        _stack.push(new StackElement(START_TXN, null));
-
-        if (_txn) {
-            s_logger.trace("txn: has already been started.");
-            return;
-        }
-
-        _txn = true;
-
-        _txnTime = System.currentTimeMillis();
-        if (_conn != null) {
-            try {
-                s_logger.trace("txn: set auto commit to false");
-                _conn.setAutoCommit(false);
-            } catch (final SQLException e) {
-                s_logger.warn("Unable to set auto commit: ", e);
-                throw new CloudRuntimeException("Unable to set auto commit: ", e);
-            }
-        }
-    }
-
-    protected void closePreviousStatement() {
-        if (_stmt != null) {
-            try {
-                if (s_stmtLogger.isTraceEnabled()) {
-                    s_stmtLogger.trace("Closing: " + _stmt.toString());
-                }
-                try {
-                    ResultSet rs = _stmt.getResultSet();
-                    if (rs != null && _stmt.getResultSetHoldability() != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
-                        rs.close();
-                    }
-                } catch(SQLException e) {
-                    s_stmtLogger.trace("Unable to close resultset");
-                }
-                _stmt.close();
-            } catch (final SQLException e) {
-                s_stmtLogger.trace("Unable to close statement: " + _stmt.toString());
-            } finally {
-                _stmt = null;
-            }
-        }
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(final String sql) throws SQLException {
-        PreparedStatement stmt = prepareStatement(sql);
-        closePreviousStatement();
-        _stmt = stmt;
-        return stmt;
-    }
-
-    public PreparedStatement prepareStatement(final String sql) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        return pstmt;
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @param autoGeneratedKeys keys that are generated
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(final String sql, final int autoGeneratedKeys) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql, autoGeneratedKeys);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        closePreviousStatement();
-        _stmt = pstmt;
-        return pstmt;
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @param columnNames names of the columns
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(final String sql, final String[] columnNames) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql, columnNames);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        closePreviousStatement();
-        _stmt = pstmt;
-        return pstmt;
-    }
-
-    /**
-     * Prepares an auto close statement.  The statement is closed automatically if it is
-     * retrieved with this method.
-     * 
-     * @param sql sql String
-     * @return PreparedStatement
-     * @throws SQLException if problem with JDBC layer.
-     * 
-     * @see java.sql.Connection
-     */
-    public PreparedStatement prepareAutoCloseStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-        final Connection conn = getConnection();
-        final PreparedStatement pstmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
-        if (s_stmtLogger.isTraceEnabled()) {
-            s_stmtLogger.trace("Preparing: " + sql);
-        }
-        closePreviousStatement();
-        _stmt = pstmt;
-        return pstmt;
-    }
-
-    /**
-     * Returns the db connection.
-     * 
-     * Note: that you can call getConnection() but beaware that
-     * all prepare statements from the Connection are not garbage
-     * collected!
-     * 
-     * @return DB Connection but make sure you understand that
-     *         you are responsible for closing the PreparedStatement.
-     * @throws SQLException
-     */
-    public Connection getConnection() throws SQLException {
-        if (_conn == null) {
-            switch (_dbId) {
-            case CLOUD_DB:
-                if(s_ds != null) {
-                    _conn = s_ds.getConnection();
-                } else {
-                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
-                }
-                break;
-            case USAGE_DB:
-                if(s_usageDS != null) {
-                    _conn = s_usageDS.getConnection();
-                } else {
-                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
-                }
-                break;
-            case AWSAPI_DB:
-        	if(s_awsapiDS != null) {
-        	    _conn = s_awsapiDS.getConnection();
-        	} else {
-        	    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                throw new CloudRuntimeException("Database is not initialized, process is dying?");
-        	}
-                break;
-
-            case SIMULATOR_DB:
-                if(s_simulatorDS != null) {
-                    _conn = s_simulatorDS.getConnection();
-                } else {
-                    s_logger.warn("A static-initialized variable becomes null, process is dying?");
-                    throw new CloudRuntimeException("Database is not initialized, process is dying?");
-                }
-                break;
-            default:
-
-        	throw new CloudRuntimeException("No database selected for the transaction");
-            }
-            _conn.setAutoCommit(!_txn);
-
-            //
-            // MySQL default transaction isolation level is REPEATABLE READ,
-            // to reduce chances of DB deadlock, we will use READ COMMITED isolation level instead
-            // see http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html
-            //
-            _stack.push(new StackElement(CREATE_CONN, null));
-            if (s_connLogger.isTraceEnabled()) {
-                s_connLogger.trace("Creating a DB connection with " + (_txn ? " txn: " : " no txn: ") + " for " + _dbId + ": dbconn" + System.identityHashCode(_conn) + ". Stack: " + buildName());
-            }
-        } else {
-            s_logger.trace("conn: Using existing DB connection");
-        }
-
-        return _conn;
-    }
-
-    protected boolean takeOver(final String name, final boolean create) {
-        if (_stack.size() != 0) {
-            if (!create) {
-                // If it is not a create transaction, then let's just use the current one.
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Using current transaction: " + toString());
-                }
-                mark(name);
-                return false;
-            }
-
-            final StackElement se = _stack.getFirst();
-            if (se.type == CREATE_TXN) {
-                // This create is called inside of another create.  Which is ok?
-                // We will let that create be responsible for cleaning up.
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Create using current transaction: " + toString());
-                }
-                mark(name);
-                return false;
-            }
-
-            s_logger.warn("Encountered a transaction that has leaked.  Cleaning up. " + toString());
-            cleanup();
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Took over the transaction: " + name);
-        }
-        _stack.push(new StackElement(create ? CREATE_TXN : CURRENT_TXN, name));
-        _name = name;
-        return true;
-    }
-
-    public void cleanup() {
-        closePreviousStatement();
-
-        removeUpTo(null, null);
-        if (_txn) {
-            rollbackTransaction();
-        }
-        _txn = false;
-        _name = null;
-
-        closeConnection();
-
-        _stack.clear();
-        Merovingian2 lockMaster = Merovingian2.getLockMaster();
-        if (lockMaster != null) {
-            lockMaster.cleanupThread();
-        }
-    }
-
-    public void close() {
-        removeUpTo(CURRENT_TXN, null);
-
-        if (_stack.size() == 0) {
-            s_logger.trace("Transaction is done");
-            cleanup();
-        }
-    }
-
-    /**
-     * close() is used by endTxn to close the connection.  This method only
-     * closes the connection if the name is the same as what's stored.
-     * 
-     * @param name
-     * @return true if this close actually closes the connection.  false if not.
-     */
-    public boolean close(final String name) {
-        if (_name == null) {    // Already cleaned up.
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Already cleaned up." + buildName());
-            }
-            return true;
-        }
-
-        if (!_name.equals(name)) {
-            close();
-            return false;
-        }
-
-        if (s_logger.isDebugEnabled() && _stack.size() > 2) {
-            s_logger.debug("Transaction is not closed properly: " + toString() + ".  Called by " + buildName());
-        }
-
-        cleanup();
-
-        s_logger.trace("All done");
-        return true;
-    }
-
-    protected boolean hasTxnInStack() {
-        return peekInStack(START_TXN) != null;
-    }
-
-    protected void clearLockTimes() {
-        if (s_lockLogger.isDebugEnabled()) {
-            for (Pair<String, Long> time : _lockTimes) {
-                s_lockLogger.trace("SQL " + time.first() + " took " + (System.currentTimeMillis() - time.second()));
-            }
-            _lockTimes.clear();
-        }
-    }
-
-    public boolean commit() {
-        if (!_txn) {
-            s_logger.warn("txn: Commit called when it is not a transaction: " + buildName());
-            return false;
-        }
-
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement st = it.next();
-            if (st.type == START_TXN) {
-                it.remove();
-                break;
-            }
-        }
-
-        if (hasTxnInStack()) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("txn: Not committing because transaction started elsewhere: " + buildName() + " / " + toString());
-            }
-            return false;
-        }
-
-        _txn = false;
-        try {
-            if (_conn != null) {
-                _conn.commit();
-                s_logger.trace("txn: DB Changes committed. Time = " + (System.currentTimeMillis() - _txnTime));
-                clearLockTimes();
-                closeConnection();
-            }
-            return true;
-        } catch (final SQLException e) {
-            rollbackTransaction();
-            throw new CloudRuntimeException("Unable to commit or close the connection. ", e);
-        }
-    }
-
-    protected void closeConnection() {
-        closePreviousStatement();
-
-        if (_conn == null) {
-            return;
-        }
-
-        if (_txn) {
-            s_connLogger.trace("txn: Not closing DB connection because we're still in a transaction.");
-            return;
-        }
-
-        try {
-            // we should only close db connection when it is not user managed
-            if (this._dbId != CONNECTED_DB) {
-                if (s_connLogger.isTraceEnabled()) {
-                    s_connLogger.trace("Closing DB connection: dbconn" + System.identityHashCode(_conn));
-                }                                
-                _conn.close();
-                _conn = null;  
-            }
-
-        } catch (final SQLException e) {
-            s_logger.warn("Unable to close connection", e);
-        }
-    }
-
-    protected void removeUpTo(String type, Object ref) {
-        boolean rollback = false;
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement item = it.next();
-
-            it.remove();
-
-            try {
-                if (item.type == type && (ref == null || item.ref == ref)) {
-                    break;
-                }
-
-                if (item.type == CURRENT_TXN) {
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Releasing the current txn: " + (item.ref != null ? item.ref : ""));
-                    }
-                } else if (item.type == CREATE_CONN) {
-                    closeConnection();
-                } else if (item.type == START_TXN) {
-                    if (item.ref == null) {
-                        rollback = true;
-                    } else {
-                        try {
-                            _conn.rollback((Savepoint)ref);
-                            rollback = false;
-                        } catch (final SQLException e) {
-                            s_logger.warn("Unable to rollback Txn.", e);
-                        }
-                    }
-                } else if (item.type == STATEMENT) {
-                    try {
-                        if (s_stmtLogger.isTraceEnabled()) {
-                            s_stmtLogger.trace("Closing: " + ref.toString());
-                        }
-                        Statement stmt = (Statement)ref;
-                        try {
-                            ResultSet rs = stmt.getResultSet();
-                            if (rs != null) {
-                                rs.close();
-                            }
-                        } catch(SQLException e) {
-                            s_stmtLogger.trace("Unable to close resultset");
-                        }
-                        stmt.close();
-                    } catch (final SQLException e) {
-                        s_stmtLogger.trace("Unable to close statement: " + item);
-                    }
-                } else if (item.type == ATTACHMENT) {
-                    TransactionAttachment att = (TransactionAttachment)item.ref;
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Cleaning up " + att.getName());
-                    }
-                    att.cleanup();
-                }
-            } catch(Exception e) {
-                s_logger.error("Unable to clean up " + item, e);
-            }
-        }
-
-        if (rollback) {
-            rollback();
-        }
-    }
-
-    protected void rollbackTransaction() {
-        closePreviousStatement();
-        if (!_txn) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Rollback called for " + _name + " when there's no transaction: " + buildName());
-            }
-            return;
-        }
-        assert (!hasTxnInStack()) : "Who's rolling back transaction when there's still txn in stack?";
-        _txn = false;
-        try {
-            if (_conn != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Rolling back the transaction: Time = " + (System.currentTimeMillis() - _txnTime) + " Name =  " + _name + "; called by " + buildName());
-                }
-                _conn.rollback();
-            }
-            clearLockTimes();
-            closeConnection();
-        } catch(final SQLException e) {
-            s_logger.warn("Unable to rollback", e);
-        }
-    }
-
-    protected void rollbackSavepoint(Savepoint sp) {
-        try {
-            if (_conn != null) {
-                _conn.rollback(sp);
-            }
-        } catch (SQLException e) {
-            s_logger.warn("Unable to rollback to savepoint " + sp);
-        }
-
-        if (!hasTxnInStack()) {
-            _txn = false;
-            closeConnection();
-        }
-    }
-
-    public void rollback() {
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement st = it.next();
-            if (st.type == START_TXN) {
-                if (st.ref == null) {
-                    it.remove();
-                } else  {
-                    rollback((Savepoint)st.ref);
-                    return;
-                }
-            }
-        }
-
-        rollbackTransaction();
-    }
-
-    public Savepoint setSavepoint() throws SQLException {
-        _txn = true;
-        StackElement st = new StackElement(START_TXN, null);
-        _stack.push(st);
-        final Connection conn = getConnection();
-        final Savepoint sp = conn.setSavepoint();
-        st.ref = sp;
-
-        return sp;
-    }
-
-    public Savepoint setSavepoint(final String name) throws SQLException {
-        _txn = true;
-        StackElement st = new StackElement(START_TXN, null);
-        _stack.push(st);
-        final Connection conn = getConnection();
-        final Savepoint sp = conn.setSavepoint(name);
-        st.ref = sp;
-
-        return sp;
-    }
-
-    public void releaseSavepoint(final Savepoint sp) throws SQLException {
-        removeTxn(sp);
-        if (_conn != null) {
-            _conn.releaseSavepoint(sp);
-        }
-
-        if (!hasTxnInStack()) {
-            _txn = false;
-            closeConnection();
-        }
-    }
-
-    protected boolean hasSavepointInStack(Savepoint sp) {
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement se = it.next();
-            if (se.type == START_TXN && se.ref == sp) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    protected void removeTxn(Savepoint sp) {
-        assert hasSavepointInStack(sp) : "Removing a save point that's not in the stack";
-
-        if (!hasSavepointInStack(sp)) {
-            return;
-        }
-
-        Iterator<StackElement> it = _stack.iterator();
-        while (it.hasNext()) {
-            StackElement se = it.next();
-            if (se.type == START_TXN) {
-                it.remove();
-                if (se.ref == sp) {
-                    return;
-                }
-            }
-        }
-    }
-
-    public void rollback(final Savepoint sp) {
-        removeTxn(sp);
-
-        rollbackSavepoint(sp);
-    }
-
-    public Connection getCurrentConnection() {
-        return _conn;
-    }
-
-    public List<StackElement> getStack() {
-        return _stack;
-    }
-
-    protected Transaction() {
-        _name = null;
-        _conn = null;
-        _stack = null;
-        _txn = false;
-        _dbId = -1;
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        if (!(_conn == null && (_stack == null || _stack.size() == 0))) {
-            assert (false) : "Oh Alex oh alex...something is wrong with how we're doing this";
-            s_logger.error("Something went wrong that a transaction is orphaned before db connection is closed");
-            cleanup();
-        }
-    }
-
-    protected class StackElement {
-        public String type;
-        public Object ref;
-
-        public StackElement (String type, Object ref) {
-            this.type = type;
-            this.ref = ref;
-        }
-
-        @Override
-        public String toString() {
-            return type + "-" + ref;
-        }
-    }
-
-    private static DataSource s_ds;
-    private static DataSource s_usageDS;
-    private static DataSource s_awsapiDS;
-    private static DataSource s_simulatorDS;
-
-    static {
-        // Initialize with assumed db.properties file
-        initDataSource("db.properties");
-    }
-
-    public static void initDataSource(String propsFileName) {
-        try {
-            File dbPropsFile = PropertiesUtil.findConfigFile(propsFileName);
-            final Properties dbProps;
-            if (EncryptionSecretKeyChecker.useEncryption()) {
-                StandardPBEStringEncryptor encryptor = EncryptionSecretKeyChecker.getEncryptor();
-                dbProps = new EncryptableProperties(encryptor);
-            } else {
-                dbProps = new Properties();
-            }
-            try {
-                dbProps.load(new FileInputStream(dbPropsFile));
-            } catch (IOException e) {
-                s_logger.fatal("Unable to load db properties file, pl. check the classpath and file path configuration", e);
-                return;
-            } catch (NullPointerException e) {
-                s_logger.fatal("Unable to locate db properties file within classpath or absolute path: " + propsFileName);
-                return;
-            }
-
-            // FIXME:  If params are missing...default them????
-            final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
-            final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle"));
-            final long cloudMaxWait = Long.parseLong(dbProps.getProperty("db.cloud.maxWait"));
-            final String cloudUsername = dbProps.getProperty("db.cloud.username");
-            final String cloudPassword = dbProps.getProperty("db.cloud.password");
-            final String cloudHost = dbProps.getProperty("db.cloud.host");
-            final int cloudPort = Integer.parseInt(dbProps.getProperty("db.cloud.port"));
-            final String cloudDbName = dbProps.getProperty("db.cloud.name");
-            final boolean cloudAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.cloud.autoReconnect"));
-            final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery");
-            final String cloudIsolationLevel = dbProps.getProperty("db.cloud.isolation.level");
-
-            int isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
-            if (cloudIsolationLevel == null) {
-                isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("readcommitted")) {
-                isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("repeatableread")) {
-                isolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("serializable")) {
-                isolationLevel = Connection.TRANSACTION_SERIALIZABLE;
-            } else if (cloudIsolationLevel.equalsIgnoreCase("readuncommitted")) {
-                isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
-            } else {
-                s_logger.warn("Unknown isolation level " + cloudIsolationLevel + ".  Using read uncommitted");
-            }
-
-            final boolean cloudTestOnBorrow = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testOnBorrow"));
-            final boolean cloudTestWhileIdle = Boolean.parseBoolean(dbProps.getProperty("db.cloud.testWhileIdle"));
-            final long cloudTimeBtwEvictionRunsMillis = Long.parseLong(dbProps.getProperty("db.cloud.timeBetweenEvictionRunsMillis"));
-            final long cloudMinEvcitableIdleTimeMillis = Long.parseLong(dbProps.getProperty("db.cloud.minEvictableIdleTimeMillis"));
-            final boolean cloudPoolPreparedStatements = Boolean.parseBoolean(dbProps.getProperty("db.cloud.poolPreparedStatements"));
-            final String url = dbProps.getProperty("db.cloud.url.params");
-
-            final boolean useSSL = Boolean.parseBoolean(dbProps.getProperty("db.cloud.useSSL"));
-            if (useSSL) {
-                System.setProperty("javax.net.ssl.keyStore", dbProps.getProperty("db.cloud.keyStore"));
-                System.setProperty("javax.net.ssl.keyStorePassword", dbProps.getProperty("db.cloud.keyStorePassword"));
-                System.setProperty("javax.net.ssl.trustStore", dbProps.getProperty("db.cloud.trustStore"));
-                System.setProperty("javax.net.ssl.trustStorePassword", dbProps.getProperty("db.cloud.trustStorePassword"));
-            }
-
-            String regionId = dbProps.getProperty("region.id");
-            if(regionId == null){
-            	s_region_id = 1;
-            } else {
-            	s_region_id = Integer.parseInt(regionId);
-            }
-            final GenericObjectPool cloudConnectionPool = new GenericObjectPool(null, cloudMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                    cloudMaxWait, cloudMaxIdle, cloudTestOnBorrow, false, cloudTimeBtwEvictionRunsMillis, 1, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle);
-
-            final ConnectionFactory cloudConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + cloudDbName +
-                    "?autoReconnect=" + cloudAutoReconnect + (url != null ? "&" + url : "") + (useSSL ? "&useSSL=true" : ""), cloudUsername, cloudPassword);
-
-            final KeyedObjectPoolFactory poolableObjFactory = (cloudPoolPreparedStatements ? new StackKeyedObjectPoolFactory() : null);
-
-            final PoolableConnectionFactory cloudPoolableConnectionFactory = new PoolableConnectionFactory(cloudConnectionFactory, cloudConnectionPool, poolableObjFactory,
-                    cloudValidationQuery, false, false, isolationLevel);
-
-            // Default Data Source for CloudStack
-            s_ds = new PoolingDataSource(cloudPoolableConnectionFactory.getPool());
-
-            // Configure the usage db
-            final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive"));
-            final int usageMaxIdle = Integer.parseInt(dbProps.getProperty("db.usage.maxIdle"));
-            final long usageMaxWait = Long.parseLong(dbProps.getProperty("db.usage.maxWait"));
-            final String usageUsername = dbProps.getProperty("db.usage.username");
-            final String usagePassword = dbProps.getProperty("db.usage.password");
-            final String usageHost = dbProps.getProperty("db.usage.host");
-            final int usagePort = Integer.parseInt(dbProps.getProperty("db.usage.port"));
-            final String usageDbName = dbProps.getProperty("db.usage.name");
-            final boolean usageAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.usage.autoReconnect"));
-            final String usageUrl = dbProps.getProperty("db.usage.url.params");
-
-            final GenericObjectPool usageConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                    usageMaxWait, usageMaxIdle);
-
-            final ConnectionFactory usageConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + usageHost + ":" + usagePort + "/" + usageDbName +
-                    "?autoReconnect=" + usageAutoReconnect + (usageUrl != null ? "&" + usageUrl : ""), usageUsername, usagePassword);
-
-            final PoolableConnectionFactory usagePoolableConnectionFactory = new PoolableConnectionFactory(usageConnectionFactory, usageConnectionPool,
-                    new StackKeyedObjectPoolFactory(), null, false, false);
-
-            // Data Source for usage server
-            s_usageDS = new PoolingDataSource(usagePoolableConnectionFactory.getPool());
-
-            // Configure awsapi db
-            final String awsapiDbName = dbProps.getProperty("db.awsapi.name");
-            final GenericObjectPool awsapiConnectionPool = new GenericObjectPool(null, usageMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                    usageMaxWait, usageMaxIdle);
-            final ConnectionFactory awsapiConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + cloudHost + ":" + cloudPort + "/" + awsapiDbName +
-                    "?autoReconnect=" + usageAutoReconnect, cloudUsername, cloudPassword);
-            final PoolableConnectionFactory awsapiPoolableConnectionFactory = new PoolableConnectionFactory(awsapiConnectionFactory, awsapiConnectionPool,
-                    new StackKeyedObjectPoolFactory(), null, false, false);
-
-            // Data Source for awsapi
-            s_awsapiDS = new PoolingDataSource(awsapiPoolableConnectionFactory.getPool());
-
-            try {
-                // Configure the simulator db
-                final int simulatorMaxActive = Integer.parseInt(dbProps.getProperty("db.simulator.maxActive"));
-                final int simulatorMaxIdle = Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle"));
-                final long simulatorMaxWait = Long.parseLong(dbProps.getProperty("db.simulator.maxWait"));
-                final String simulatorUsername = dbProps.getProperty("db.simulator.username");
-                final String simulatorPassword = dbProps.getProperty("db.simulator.password");
-                final String simulatorHost = dbProps.getProperty("db.simulator.host");
-                final int simulatorPort = Integer.parseInt(dbProps.getProperty("db.simulator.port"));
-                final String simulatorDbName = dbProps.getProperty("db.simulator.name");
-                final boolean simulatorAutoReconnect = Boolean.parseBoolean(dbProps.getProperty("db.simulator.autoReconnect"));
-
-                final GenericObjectPool simulatorConnectionPool = new GenericObjectPool(null, simulatorMaxActive, GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
-                        simulatorMaxWait, simulatorMaxIdle);
-
-                final ConnectionFactory simulatorConnectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://" + simulatorHost + ":" + simulatorPort + "/" + simulatorDbName +
-                        "?autoReconnect=" + simulatorAutoReconnect, simulatorUsername, simulatorPassword);
-
-                final PoolableConnectionFactory simulatorPoolableConnectionFactory = new PoolableConnectionFactory(simulatorConnectionFactory, simulatorConnectionPool,
-                        new StackKeyedObjectPoolFactory(), null, false, false);
-                s_simulatorDS = new PoolingDataSource(simulatorPoolableConnectionFactory.getPool());
-            } catch (Exception e) {
-                s_logger.debug("Simulator DB properties are not available. Not initializing simulator DS");
-            }
-        } catch (final Exception e) {
-            s_ds = getDefaultDataSource("cloud");
-            s_usageDS = getDefaultDataSource("cloud_usage");
-            s_simulatorDS = getDefaultDataSource("cloud_simulator");
-            s_logger.warn("Unable to load db configuration, using defaults with 5 connections. Falling back on assumed datasource on localhost:3306 using username:password=cloud:cloud. Please check your configuration", e);
-        }
-    }
-
-    private static DataSource getDefaultDataSource(final String database) {
-        final GenericObjectPool connectionPool = new GenericObjectPool(null, 5);
-        final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
-           "jdbc:mysql://localhost:3306/" + database, "cloud", "cloud");
-        final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
-           connectionFactory, connectionPool, null, null, false, true);
-        return new PoolingDataSource(
-           /* connectionPool */poolableConnectionFactory.getPool());
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f5e5b39c/utils/src/com/cloud/utils/db/TransactionAttachment.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/TransactionAttachment.java b/utils/src/com/cloud/utils/db/TransactionAttachment.java
deleted file mode 100644
index 198f74c..0000000
--- a/utils/src/com/cloud/utils/db/TransactionAttachment.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-/**
- * TransactionAttachment are objects added to Transaction such that when
- * the in memory transaction is closed, they are automatically closed.
- *
- */
-public interface TransactionAttachment {
-    /**
-     * @return a unique name to be inserted.
-     */
-    String getName();
-    
-    /**
-     * cleanup() if it wasn't cleaned up before.
-     */
-    void cleanup();
-}