Liran Zelkha has uploaded a new change for review.

Change subject: core: WIP: Adding JPA to ovirt
......................................................................

core: WIP: Adding JPA to ovirt

This patch will introduce the neccessary infrastructure to use JPA in ovirt.
A first candidate, implemented in this patch, will be the VdsGroup entity.

The goal is to allow ovirt to enjoy JPA/hibernate capabilities:
1. 1st level caching of multiple queries to the same entity in the same
   transaction.
2. Lazy loading for large objects (such as VDS, VM, etc).

In the future we can explore features like:
1. 2nd level caching (based on Infinispan)
2. Cross-database support

Future patches will move additional entities to JPA.

Change-Id: I3cd0bbf9f0913955cb3e1facfa9a4bdc1f1ab24d
Signed-off-by: [email protected] <[email protected]>
---
M backend/manager/modules/common/pom.xml
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDSGroup.java
M backend/manager/modules/dal/pom.xml
A 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/GuidMapper.java
A 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/HibernateFacade.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsGroupDAODbFacadeImpl.java
A backend/manager/modules/dal/src/main/resources/META-INF/persistence.xml
A backend/manager/modules/dal/src/test/java/META-INF/persistence.xml
M 
backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VdsGroupDAOTest.java
9 files changed, 246 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/06/22806/1

diff --git a/backend/manager/modules/common/pom.xml 
b/backend/manager/modules/common/pom.xml
index d2dd9ed..c4b098d 100644
--- a/backend/manager/modules/common/pom.xml
+++ b/backend/manager/modules/common/pom.xml
@@ -47,6 +47,12 @@
       <scope>provided</scope>
     </dependency>
 
+    <dependency>
+      <groupId>org.hibernate</groupId>
+      <artifactId>hibernate-entitymanager</artifactId>
+      <version>4.3.0.Final</version>
+    </dependency>    
+
   </dependencies>
 
   <build>
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDSGroup.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDSGroup.java
index 6de8a5e..51bffe2 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDSGroup.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VDSGroup.java
@@ -2,8 +2,16 @@
 
 import java.io.Serializable;
 import java.util.Map;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
+
+import org.hibernate.annotations.Type;
 import org.ovirt.engine.core.common.scheduling.OptimizationType;
 import org.ovirt.engine.core.common.utils.ObjectUtils;
 import org.ovirt.engine.core.common.validation.annotation.ValidI18NName;
@@ -16,10 +24,15 @@
 
 @ValidVdsGroup(groups = { CreateEntity.class })
 
+@Entity
+@Table(name = "vds_groups")
 public class VDSGroup extends IVdcQueryable implements Serializable, 
BusinessEntity<Guid>, HasStoragePool<Guid>, Nameable, Commented {
 
     private static final long serialVersionUID = 5659359762655478095L;
 
+    @Id
+    @Column(name = "vds_group_id")
+    @Type(type = "org.ovirt.engine.core.dao.GuidMapper")
     private Guid id;
 
     @NotNull(message = "VALIDATION.VDS_GROUP.NAME.NOT_NULL", groups = { 
CreateEntity.class, UpdateEntity.class })
@@ -27,49 +40,71 @@
             groups = {
             CreateEntity.class, UpdateEntity.class })
     @ValidI18NName(message = "VALIDATION.VDS_GROUP.NAME.INVALID", groups = { 
CreateEntity.class, UpdateEntity.class })
+    @Column(name = "name")
     private String name;
 
     @Size(max = BusinessEntitiesDefinitions.GENERAL_MAX_SIZE)
+    @Column(name = "description")
     private String description;
 
+    @Transient
     private String comment;
 
     @Size(max = BusinessEntitiesDefinitions.CLUSTER_CPU_NAME_SIZE)
+    @Column(name = "cpu_name")
     private String cpu_name;
 
+    @Column(name = "storage_pool_id")
+    @Type(type = "org.ovirt.engine.core.dao.GuidMapper")
     private Guid storagePoolId;
 
     @Size(max = BusinessEntitiesDefinitions.DATACENTER_NAME_SIZE)
+    @Transient
     private String storagePoolName;
 
+    @Column(name = "max_vds_memory_over_commit")
     private int max_vds_memory_over_commit;
 
+    @Column(name = "enable_balloon")
     private boolean enableBallooning;
 
+    @Column(name = "count_threads_as_cores")
     private boolean countThreadsAsCores;
 
     @Size(max = BusinessEntitiesDefinitions.GENERAL_VERSION_SIZE)
+    @Column(name = "compatibility_version")
     private String compatibility_version;
 
+    @Transient
     private Version compatVersion;
 
+    @Column(name = "transparent_hugepages")
     private boolean transparentHugepages;
 
     @NotNull(message = "VALIDATION.VDS_GROUP.MigrateOnError.NOT_NULL")
+    @Column(name = "migrate_on_error")
     private MigrateOnErrorOptions migrateOnError;
 
+    @Column(name = "virt_service")
     private boolean virtService;
 
+    @Column(name = "gluster_service")
     private boolean glusterService;
 
+    @Column(name = "tunnel_migration")
     private boolean tunnelMigration;
 
+    @Column(name = "emulated_machine")
     private String emulatedMachine;
 
+    @Column(name = "trusted_service")
     private boolean trustedService;
 
+    @Column(name = "cluster_policy_id")
+    @Type(type = "org.ovirt.engine.core.dao.GuidMapper")
     private Guid clusterPolicyId;
 
+    @Transient
     private String clusterPolicyName;
 
     @ValidUri(message = "VALIDATION.VDS_GROUP.SPICE_PROXY.HOSTNAME_OR_IP",
@@ -77,10 +112,16 @@
     @Size(max = BusinessEntitiesDefinitions.SPICE_PROXY_ADDR_SIZE)
     private String spiceProxy;
 
+    @Transient
     private Map<String, String> clusterPolicyProperties;
+
+    @Column(name = "detect_emulated_machine")
     private boolean detectEmulatedMachine;
 
+    @Transient
     private ArchitectureType architecture;
+
+    @Transient
     private OptimizationType optimizationType;
 
     public VDSGroup() {
diff --git a/backend/manager/modules/dal/pom.xml 
b/backend/manager/modules/dal/pom.xml
index 33e08c5..0ac279d 100644
--- a/backend/manager/modules/dal/pom.xml
+++ b/backend/manager/modules/dal/pom.xml
@@ -84,6 +84,11 @@
       <groupId>org.infinispan</groupId>
       <artifactId>infinispan-core</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.hibernate</groupId>
+      <artifactId>hibernate-entitymanager</artifactId>
+      <version>4.3.0.Final</version>
+    </dependency>    
   </dependencies>
   <build>
     <filters>
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/GuidMapper.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/GuidMapper.java
new file mode 100644
index 0000000..fd9bbb5
--- /dev/null
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/GuidMapper.java
@@ -0,0 +1,99 @@
+package org.ovirt.engine.core.dao;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.UUID;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.usertype.UserType;
+import org.ovirt.engine.core.compat.Guid;
+
+public class GuidMapper implements UserType {
+
+    @Override
+    public Object assemble(Serializable cached, Object owner) throws 
HibernateException {
+        return cached;
+    }
+
+    @Override
+    public Object deepCopy(Object val) throws HibernateException {
+        if (val == null)
+            return null;
+
+        if (val instanceof byte[]) {
+            return new Guid((byte[]) val, true);
+        }
+
+        if (val instanceof UUID)
+            return new Guid((UUID) val);
+
+        if (val instanceof Guid)
+            return new Guid(((Guid) val).getUuid());
+
+        throw new UnsupportedOperationException("Can't convert " + 
val.getClass() + " to GUID");
+    }
+
+    @Override
+    public Serializable disassemble(Object val) throws HibernateException {
+        if (val instanceof byte[]) {
+            return new Guid((byte[]) val, true);
+        }
+
+        if (val instanceof UUID)
+            return new Guid((UUID) val);
+
+        throw new UnsupportedOperationException("Can't convert " + 
val.getClass() + " to GUID");
+    }
+
+    @Override
+    public boolean equals(Object x, Object y) throws HibernateException {
+        return x.equals(y);
+    }
+
+    @Override
+    public int hashCode(Object value) throws HibernateException {
+        return value.hashCode();
+    }
+
+    @Override
+    public boolean isMutable() {
+        return true;
+    }
+
+    @Override
+    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor 
si, Object owner)
+            throws HibernateException, SQLException {
+
+        Object value = rs.getObject(names[0]);
+        if (value == null)
+            return null;
+
+        return new Guid((UUID) value);
+    }
+
+    @Override
+    public void nullSafeSet(PreparedStatement stmt, Object value, int index, 
SessionImplementor si)
+            throws HibernateException, SQLException {
+        stmt.setObject(index, ((Guid) value).getUuid());
+    }
+
+    @Override
+    public Object replace(Object original, Object target, Object owner) throws 
HibernateException {
+        return original;
+    }
+
+    @Override
+    public Class returnedClass() {
+        return Guid.class;
+    }
+
+    @Override
+    public int[] sqlTypes() {
+        return new int[] { Types.BLOB };
+    }
+
+}
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/HibernateFacade.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/HibernateFacade.java
new file mode 100644
index 0000000..8ff84a4
--- /dev/null
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/HibernateFacade.java
@@ -0,0 +1,29 @@
+package org.ovirt.engine.core.dao;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+public abstract class HibernateFacade extends BaseDAODbFacade {
+    private static volatile EntityManagerFactory emf;
+
+    protected EntityManager getEntityManager() {
+        if (emf == null) {
+            synchronized (HibernateFacade.class) {
+                if (emf == null) {
+                    emf = Persistence.createEntityManagerFactory("ovirt");
+                }
+            }
+        }
+        return emf.createEntityManager();
+    }
+
+    public static EntityManagerFactory getEntityManagerFactory() {
+        return emf;
+    }
+
+    public static void setEntityManagerFactory(EntityManagerFactory emf) {
+        HibernateFacade.emf = emf;
+    }
+
+}
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsGroupDAODbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsGroupDAODbFacadeImpl.java
index ce4a1bc..1cee643 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsGroupDAODbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/VdsGroupDAODbFacadeImpl.java
@@ -5,6 +5,11 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
 import org.ovirt.engine.core.common.businessentities.ActionGroup;
 import org.ovirt.engine.core.common.businessentities.ArchitectureType;
 import org.ovirt.engine.core.common.businessentities.MigrateOnErrorOptions;
@@ -22,18 +27,23 @@
  * found in {@link org.ovirt.engine.core.dal.dbbroker.DbFacade}.
  *
  */
-public class VdsGroupDAODbFacadeImpl extends BaseDAODbFacade implements 
VdsGroupDAO {
+public class VdsGroupDAODbFacadeImpl extends HibernateFacade implements 
VdsGroupDAO {
     @Override
     public VDSGroup get(Guid id) {
-        return get(id, null, false);
+        return getEntityManager().find(VDSGroup.class, id);
     }
 
     @Override
     public VDSGroup get(Guid id, Guid userID, boolean isFiltered) {
-        MapSqlParameterSource parameterSource = 
getCustomMapSqlParameterSource()
-                .addValue("vds_group_id", id).addValue("user_id", 
userID).addValue("is_filtered", isFiltered);
+        EntityManager em = getEntityManager();
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<VDSGroup> query = cb.createQuery(VDSGroup.class);
+        Root<VDSGroup> group = query.from(VDSGroup.class);
+        query.where(cb.and(cb.equal(group.get("id"), id),
+                cb.and(cb.equal(group.get("user_id"), userID),
+                        cb.equal(group.get("is_filtered"), isFiltered))));
 
-        return getCallsHandler().executeRead("GetVdsGroupByVdsGroupId", 
VdsGroupRowMapper.instance, parameterSource);
+        return em.createQuery(query).getSingleResult();
     }
 
     @Override
diff --git 
a/backend/manager/modules/dal/src/main/resources/META-INF/persistence.xml 
b/backend/manager/modules/dal/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..e48edd9
--- /dev/null
+++ b/backend/manager/modules/dal/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,12 @@
+<persistence xmlns="http://java.sun.com/xml/ns/persistence";
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd";
+             version="2.0">
+   <persistence-unit name="ovirt">
+         <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+      <class>org.ovirt.engine.core.common.businessentities.VDSGroup</class>
+      <properties>
+          <property name="hibernate.dialect" 
value="org.hibernate.dialect.PostgreSQLDialect" />
+      </properties>
+   </persistence-unit>
+</persistence>           
diff --git a/backend/manager/modules/dal/src/test/java/META-INF/persistence.xml 
b/backend/manager/modules/dal/src/test/java/META-INF/persistence.xml
new file mode 100644
index 0000000..366135a
--- /dev/null
+++ b/backend/manager/modules/dal/src/test/java/META-INF/persistence.xml
@@ -0,0 +1,12 @@
+<persistence>
+       <persistence-unit name="ovirt">
+               
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+               <properties>
+                       <property name="javax.persistence.jdbc.driver" 
value="${engine.db.driver}" />
+                       <property name="javax.persistence.jdbc.user" 
value="${engine.db.username}" />
+                       <property name="javax.persistence.jdbc.password" 
value="${engine.db.password}" />
+                       <property name="javax.persistence.jdbc.url" 
value="${engine.db.url}" />
+                       <property name="hibernate.dialect" 
value="org.hibernate.dialect.HSQLDialect" />
+               </properties>
+       </persistence-unit>
+</persistence>
diff --git 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VdsGroupDAOTest.java
 
b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VdsGroupDAOTest.java
index fab5f1b..ededb8c 100644
--- 
a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VdsGroupDAOTest.java
+++ 
b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/VdsGroupDAOTest.java
@@ -7,9 +7,16 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
 
 import org.junit.Test;
 import org.ovirt.engine.core.common.businessentities.ArchitectureType;
@@ -37,6 +44,26 @@
     public void setUp() throws Exception {
         super.setUp();
 
+        Properties properties = new Properties();
+
+        InputStream is = null;
+        is = 
BaseDAOTestCase.class.getResourceAsStream("/test-database.properties");
+        try {
+            properties.load(is);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        Map props = new HashMap();
+        props.put("javax.persistence.jdbc.driver", 
properties.getProperty("database.driver"));
+        props.put("javax.persistence.jdbc.user", 
properties.getProperty("database.username"));
+        props.put("javax.persistence.jdbc.password", 
properties.getProperty("database.password"));
+        props.put("javax.persistence.jdbc.url", 
properties.getProperty("database.url"));
+
+        EntityManagerFactory emf = 
Persistence.createEntityManagerFactory("ovirt", props);
+
+        HibernateFacade.setEntityManagerFactory(emf);
+
         VdsDAO vdsDAO = dbFacade.getVdsDao();
 
         existingVds = vdsDAO.get(FixturesTool.VDS_RHEL6_NFS_SPM);
@@ -63,7 +90,6 @@
         newGroup.setDetectEmulatedMachine(true);
         newGroup.setEmulatedMachine("rhel6.4.0");
         newGroup.setArchitecture(ArchitectureType.x86_64);
-
     }
 
     /**


-- 
To view, visit http://gerrit.ovirt.org/22806
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3cd0bbf9f0913955cb3e1facfa9a4bdc1f1ab24d
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Liran Zelkha <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to