CLOUDSTACK-2568: ACS41 regression in storage subsystem (seen with local storage and 2 or more hosts)

Changes:
- In VolumeReservationVO, the  getter method of a column had a typo, causing us to create a wrong searchbuilder. It was searching over the 'id' column instead of 'vm_reservation_id' causing
- This bug was causing the vm deployment to choose a wrong pool during deployment since the search was choosing incorrectly
- This bug in the GenericSearchBuilder is also fixed - if the getter method does not use the standard 'get' or 'is' prefix, one should annotate that method using
 @Column(name = "<column_name>") and indicate which column this method refers to. This will cause the GenericSearchBuilder to identify the field correctly.
This commit is contained in:
Prachi Damle 2013-05-21 16:05:07 -07:00
parent 0a443697ea
commit dce4258171
3 changed files with 15 additions and 27 deletions

View File

@ -16,22 +16,14 @@
// under the License. // under the License.
package org.apache.cloudstack.engine.cloud.entity.api.db; package org.apache.cloudstack.engine.cloud.entity.api.db;
import java.util.Date;
import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Transient;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.utils.db.GenericDao;
@Entity @Entity
@Table(name = "volume_reservation") @Table(name = "volume_reservation")
public class VolumeReservationVO implements InternalIdentity{ public class VolumeReservationVO implements InternalIdentity{
@ -42,7 +34,7 @@ public class VolumeReservationVO implements InternalIdentity{
private long id; private long id;
@Column(name = "vm_reservation_id") @Column(name = "vm_reservation_id")
private Long vmReservationId; private long vmReservationId;
@Column(name = "vm_id") @Column(name = "vm_id")
private long vmId; private long vmId;
@ -53,10 +45,6 @@ public class VolumeReservationVO implements InternalIdentity{
@Column(name="pool_id") @Column(name="pool_id")
private long poolId; private long poolId;
// VolumeId -> poolId
@Transient
Map<String, String> volumeReservationMap;
/** /**
* There should never be a public constructor for this class. Since it's * There should never be a public constructor for this class. Since it's
* only here to define the table for the DAO class. * only here to define the table for the DAO class.
@ -64,7 +52,7 @@ public class VolumeReservationVO implements InternalIdentity{
protected VolumeReservationVO() { protected VolumeReservationVO() {
} }
public VolumeReservationVO(long vmId, long volumeId, long poolId, Long vmReservationId) { public VolumeReservationVO(long vmId, long volumeId, long poolId, long vmReservationId) {
this.vmId = vmId; this.vmId = vmId;
this.volumeId = volumeId; this.volumeId = volumeId;
this.poolId = poolId; this.poolId = poolId;
@ -80,7 +68,7 @@ public class VolumeReservationVO implements InternalIdentity{
return vmId; return vmId;
} }
public Long geVmReservationId() { public long getVmReservationId() {
return vmReservationId; return vmReservationId;
} }
@ -93,8 +81,4 @@ public class VolumeReservationVO implements InternalIdentity{
} }
public Map<String,String> getVolumeReservation(){
return volumeReservationMap;
}
} }

View File

@ -49,7 +49,7 @@ public class VolumeReservationDaoImpl extends GenericDaoBase<VolumeReservationVO
VmIdSearch.done(); VmIdSearch.done();
VmReservationIdSearch = createSearchBuilder(); VmReservationIdSearch = createSearchBuilder();
VmReservationIdSearch.and("vmReservationId", VmReservationIdSearch.entity().geVmReservationId(), SearchCriteria.Op.EQ); VmReservationIdSearch.and("vmReservationId", VmReservationIdSearch.entity().getVmReservationId(), SearchCriteria.Op.EQ);
VmReservationIdSearch.done(); VmReservationIdSearch.done();
} }

View File

@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Transient; import javax.persistence.Transient;
import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.Factory;
@ -163,13 +164,16 @@ public class GenericSearchBuilder<T, K> implements MethodInterceptor {
set(fieldName); set(fieldName);
return null; return null;
} else { } else {
name = name.toLowerCase(); Column ann = method.getAnnotation(Column.class);
for (String fieldName : _attrs.keySet()) { if (ann != null) {
if (name.endsWith(fieldName.toLowerCase())) { String colName = ann.name();
set(fieldName); for (Map.Entry<String, Attribute> attr : _attrs.entrySet()) {
if (colName.equals(attr.getValue().columnName)) {
set(attr.getKey());
return null; return null;
} }
} }
}
assert false : "Perhaps you need to make the method start with get or is?"; assert false : "Perhaps you need to make the method start with get or is?";
} }
} }