diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java b/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java index b532c2848a7..74a42f2612a 100644 --- a/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java @@ -28,6 +28,16 @@ public class ObjectStoreDetailResponse extends BaseResponse { @SerializedName("value") @Param(description="detail property value of the object store") private String value; + public ObjectStoreDetailResponse(){ + super(); + } + + public ObjectStoreDetailResponse(String name, String val){ + super(); + this.name = name; + this.value = val; + } + public String getName() { return name; } @@ -44,5 +54,33 @@ public class ObjectStoreDetailResponse extends BaseResponse { this.value = value; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + String oid = this.getName(); + result = prime * result + ((oid== null) ? 0 : oid.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ObjectStoreDetailResponse other = (ObjectStoreDetailResponse) obj; + String oid = this.getName(); + if (oid == null) { + if (other.getName() != null) + return false; + } else if (!oid.equals(other.getName())) + return false; + else if ( this.getValue().equals(other.getValue())) + return false; + return true; + } } diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java b/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java index de3a26f27d6..595ae9732e0 100644 --- a/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java @@ -16,9 +16,8 @@ // under the License. package org.apache.cloudstack.api.response; -import java.util.Date; - -import javax.persistence.Column; +import java.util.LinkedHashSet; +import java.util.Set; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -27,8 +26,6 @@ import org.apache.cloudstack.api.EntityReference; import com.cloud.serializer.Param; import com.cloud.storage.ObjectStore; import com.cloud.storage.ScopeType; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolStatus; import com.google.gson.annotations.SerializedName; @EntityReference(value=ObjectStore.class) @@ -43,7 +40,7 @@ public class ObjectStoreResponse extends BaseResponse { private String zoneName; @SerializedName("regionid") @Param(description="the Region ID of the object store") - private String regionId; + private Long regionId; @SerializedName("regionname") @Param(description="the Region name of the object store") private String regionName; @@ -54,16 +51,22 @@ public class ObjectStoreResponse extends BaseResponse { @SerializedName("url") @Param(description="the url of the object store") private String url; + @SerializedName("protocol") @Param(description="the protocol of the object store") + private String protocol; + @SerializedName("providername") @Param(description="the provider name of the object store") private String providerName; @SerializedName("scope") @Param(description="the scope of the object store") - private ScopeType type; + private ScopeType scope; @SerializedName("details") @Param(description="the details of the object store") - private String details; + private Set details; + public ObjectStoreResponse(){ + this.details = new LinkedHashSet(); + } @Override public String getObjectId() { @@ -95,11 +98,11 @@ public class ObjectStoreResponse extends BaseResponse { } - public String getRegionId() { + public Long getRegionId() { return regionId; } - public void setRegionId(String regionId) { + public void setRegionId(Long regionId) { this.regionId = regionId; } @@ -135,22 +138,35 @@ public class ObjectStoreResponse extends BaseResponse { this.providerName = providerName; } - public ScopeType getType() { - return type; + public ScopeType getScope() { + return scope; } - public void setType(ScopeType type) { - this.type = type; + public void setScope(ScopeType type) { + this.scope = type; } - public String getDetails() { + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public Set getDetails() { return details; } - public void setDetails(String details) { + public void setDetails(Set details) { this.details = details; } + public void addDetail(ObjectStoreDetailResponse detail){ + this.details.add(detail); + } + } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java new file mode 100644 index 00000000000..c980cf15693 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.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 org.apache.cloudstack.storage.datastore.db; + +import org.apache.cloudstack.api.InternalIdentity; + +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="image_data_store_details") +public class ImageDataStoreDetailVO implements InternalIdentity { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="store_id") + long storeId; + + @Column(name="name") + String name; + + @Column(name="value") + String value; + + public ImageDataStoreDetailVO(long storeId, String name, String value) { + this.storeId = storeId; + this.name = name; + this.value = value; + } + + public long getId() { + return id; + } + + public long getStoreId() { + return storeId; + } + + public void setStoreId(long storeId) { + this.storeId = storeId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + protected ImageDataStoreDetailVO() { + } +} diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java new file mode 100644 index 00000000000..781efcfb95e --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java @@ -0,0 +1,28 @@ +// 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 org.apache.cloudstack.storage.datastore.db; + +import java.util.Map; + + +import com.cloud.utils.db.GenericDao; + +public interface ImageDataStoreDetailsDao extends GenericDao { + + void update(long storeId, Map details); + Map getDetails(long storeId); +} diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 7b441901d5e..41f0759152f 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -34,6 +34,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; import org.apache.cloudstack.api.response.ProjectInvitationResponse; import org.apache.cloudstack.api.response.ProjectResponse; @@ -55,6 +56,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; import com.cloud.api.query.dao.DomainRouterJoinDao; import com.cloud.api.query.dao.HostJoinDao; +import com.cloud.api.query.dao.ImageDataStoreJoinDao; import com.cloud.api.query.dao.InstanceGroupJoinDao; import com.cloud.api.query.dao.ProjectAccountJoinDao; import com.cloud.api.query.dao.ProjectInvitationJoinDao; @@ -73,6 +75,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -284,7 +287,7 @@ public class ApiDBUtils { static NetworkModel _networkModel; static NetworkManager _networkMgr; static TemplateManager _templateMgr; - + static StatsCollector _statsCollector; static AccountDao _accountDao; @@ -362,6 +365,7 @@ public class ApiDBUtils { static HostJoinDao _hostJoinDao; static VolumeJoinDao _volJoinDao; static StoragePoolJoinDao _poolJoinDao; + static ImageDataStoreJoinDao _imageStoreJoinDao; static AccountJoinDao _accountJoinDao; static AsyncJobJoinDao _jobJoinDao; @@ -466,6 +470,7 @@ public class ApiDBUtils { @Inject private HostJoinDao hostJoinDao; @Inject private VolumeJoinDao volJoinDao; @Inject private StoragePoolJoinDao poolJoinDao; + @Inject private ImageDataStoreJoinDao imageStoreJoinDao; @Inject private AccountJoinDao accountJoinDao; @Inject private AsyncJobJoinDao jobJoinDao; @@ -566,6 +571,7 @@ public class ApiDBUtils { _hostJoinDao = hostJoinDao; _volJoinDao = volJoinDao; _poolJoinDao = poolJoinDao; + _imageStoreJoinDao = imageStoreJoinDao; _accountJoinDao = accountJoinDao; _jobJoinDao = jobJoinDao; @@ -1535,6 +1541,18 @@ public class ApiDBUtils { return _poolJoinDao.newStoragePoolView(vr); } + public static ObjectStoreResponse newImageStoreResponse(ImageDataStoreJoinVO vr) { + return _imageStoreJoinDao.newObjectStoreResponse(vr); + } + + public static ObjectStoreResponse fillImageStoreDetails(ObjectStoreResponse vrData, ImageDataStoreJoinVO vr){ + return _imageStoreJoinDao.setObjectStoreResponse(vrData, vr); + } + + public static List newImageStoreView(ObjectStore vr){ + return _imageStoreJoinDao.newObjectStoreView(vr); + } + public static AccountResponse newAccountResponse(AccountJoinVO ve) { return _accountJoinDao.newAccountResponse(ve); @@ -1579,7 +1597,7 @@ public class ApiDBUtils { public static DataCenterJoinVO newDataCenterView(DataCenter dc){ return _dcJoinDao.newDataCenterView(dc); } - + public static Map findHostDetailsById(long hostId){ return _hostDetailsDao.findDetails(hostId); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 90543316cf5..03ed97da640 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -142,6 +142,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -892,8 +893,12 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public ObjectStoreResponse createObjectStoreResponse(ObjectStore os) { - // TODO Auto-generated method stub - return null; + List viewStores = ApiDBUtils.newImageStoreView(os); + List listStores = ViewResponseHelper.createObjectStoreResponse(viewStores.toArray(new ImageDataStoreJoinVO[viewStores.size()])); + assert listStores != null && listStores.size() == 1 : "There should be one image data store returned"; + return listStores.get(0); + + } diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 9e612b07d1b..a1d1bf824a1 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; import org.apache.cloudstack.api.response.ProjectInvitationResponse; import org.apache.cloudstack.api.response.ProjectResponse; @@ -51,6 +52,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -263,6 +265,24 @@ public class ViewResponseHelper { return new ArrayList(vrDataList.values()); } + public static List createObjectStoreResponse(ImageDataStoreJoinVO... stores) { + Hashtable vrDataList = new Hashtable(); + // Initialise the vrdatalist with the input data + for (ImageDataStoreJoinVO vr : stores) { + ObjectStoreResponse vrData = vrDataList.get(vr.getId()); + if ( vrData == null ){ + // first time encountering this vm + vrData = ApiDBUtils.newImageStoreResponse(vr); + } + else{ + // update tags + vrData = ApiDBUtils.fillImageStoreDetails(vrData, vr); + } + vrDataList.put(vr.getId(), vrData); + } + return new ArrayList(vrDataList.values()); + } + public static List createAccountResponse(AccountJoinVO... accounts) { List respList = new ArrayList(); diff --git a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java new file mode 100644 index 00000000000..b92fbe60f4b --- /dev/null +++ b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java @@ -0,0 +1,36 @@ +// 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.api.query.dao; + +import java.util.List; + +import org.apache.cloudstack.api.response.ObjectStoreResponse; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.storage.ObjectStore; +import com.cloud.utils.db.GenericDao; + +public interface ImageDataStoreJoinDao extends GenericDao { + + ObjectStoreResponse newObjectStoreResponse(ImageDataStoreJoinVO os); + + ObjectStoreResponse setObjectStoreResponse(ObjectStoreResponse response, ImageDataStoreJoinVO os); + + List newObjectStoreView(ObjectStore os); + + List searchByIds(Long... spIds); + +} diff --git a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java new file mode 100644 index 00000000000..c58f954e03a --- /dev/null +++ b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java @@ -0,0 +1,164 @@ +// 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.api.query.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.api.response.ObjectStoreDetailResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.storage.ObjectStore; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + + +@Component +@Local(value={ImageDataStoreJoinDao.class}) +public class ImageDataStoreJoinDaoImpl extends GenericDaoBase implements ImageDataStoreJoinDao { + public static final Logger s_logger = Logger.getLogger(ImageDataStoreJoinDaoImpl.class); + + @Inject + private ConfigurationDao _configDao; + + private final SearchBuilder dsSearch; + + private final SearchBuilder dsIdSearch; + + + protected ImageDataStoreJoinDaoImpl() { + + dsSearch = createSearchBuilder(); + dsSearch.and("idIN", dsSearch.entity().getId(), SearchCriteria.Op.IN); + dsSearch.done(); + + dsIdSearch = createSearchBuilder(); + dsIdSearch.and("id", dsIdSearch.entity().getId(), SearchCriteria.Op.EQ); + dsIdSearch.done(); + + this._count = "select count(distinct id) from image_data_store_view WHERE "; + } + + + + + + @Override + public ObjectStoreResponse newObjectStoreResponse(ImageDataStoreJoinVO ids) { + ObjectStoreResponse osResponse = new ObjectStoreResponse(); + osResponse.setId(ids.getUuid()); + osResponse.setName(ids.getName()); + osResponse.setProviderName(ids.getProviderName()); + osResponse.setProtocol(ids.getProtocol()); + osResponse.setUrl(ids.getUrl()); + osResponse.setScope(ids.getScope()); + osResponse.setZoneId(ids.getZoneUuid()); + osResponse.setZoneName(ids.getZoneName()); + osResponse.setRegionId(ids.getRegionId()); + osResponse.setRegionName(ids.getRegionName()); + + String detailName = ids.getDetailName(); + if ( detailName != null && detailName.length() > 0 ){ + ObjectStoreDetailResponse osdResponse = new ObjectStoreDetailResponse(detailName, ids.getDetailValue()); + osResponse.addDetail(osdResponse); + } + osResponse.setObjectName("objectstore"); + return osResponse; + } + + + + + + @Override + public ObjectStoreResponse setObjectStoreResponse(ObjectStoreResponse response, ImageDataStoreJoinVO ids) { + String detailName = ids.getDetailName(); + if ( detailName != null && detailName.length() > 0 ){ + ObjectStoreDetailResponse osdResponse = new ObjectStoreDetailResponse(detailName, ids.getDetailValue()); + response.addDetail(osdResponse); + } + return response; + } + + + + @Override + public List newObjectStoreView(ObjectStore os) { + SearchCriteria sc = dsIdSearch.create(); + sc.setParameters("id", os.getId()); + return searchIncludingRemoved(sc, null, null, false); + + } + + + + @Override + public List searchByIds(Long... spIds) { + // set detail batch query size + int DETAILS_BATCH_SIZE = 2000; + String batchCfg = _configDao.getValue("detail.batch.query.size"); + if ( batchCfg != null ){ + DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg); + } + // query details by batches + List uvList = new ArrayList(); + // query details by batches + int curr_index = 0; + if ( spIds.length > DETAILS_BATCH_SIZE ){ + while ( (curr_index + DETAILS_BATCH_SIZE ) <= spIds.length ) { + Long[] ids = new Long[DETAILS_BATCH_SIZE]; + for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) { + ids[k] = spIds[j]; + } + SearchCriteria sc = dsSearch.create(); + sc.setParameters("idIN", ids); + List vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + curr_index += DETAILS_BATCH_SIZE; + } + } + if (curr_index < spIds.length) { + int batch_size = (spIds.length - curr_index); + // set the ids value + Long[] ids = new Long[batch_size]; + for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) { + ids[k] = spIds[j]; + } + SearchCriteria sc = dsSearch.create(); + sc.setParameters("idIN", ids); + List vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + } + return uvList; + } + + + + +} diff --git a/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java b/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java new file mode 100644 index 00000000000..5858dffb148 --- /dev/null +++ b/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java @@ -0,0 +1,201 @@ +// 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.api.query.vo; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; +import com.cloud.storage.ScopeType; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +/** + * Image Data Store DB view. + * + */ +@Entity +@Table(name="image_data_store_view") +public class ImageDataStoreJoinVO extends BaseViewVO implements InternalIdentity, Identity { + + @Id + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="name") + private String name; + + @Column(name="url") + private String url; + + @Column(name = "protocol") + private String protocol; + + @Column(name = "provider_name", nullable = false) + private String providerName; + + @Column(name="scope") + @Enumerated(value = EnumType.STRING) + private ScopeType scope; + + @Column(name="data_center_id") + private long zoneId; + + @Column(name="data_center_uuid") + private String zoneUuid; + + @Column(name="data_center_name") + private String zoneName; + + @Column(name="region_id") + private long regionId; + + @Column(name="region_name") + private String regionName; + + @Column(name="detail_name") + private String detailName; + + @Column(name="detail_value") + private String detailValue; + + + @Override + public long getId() { + return id; + } + + @Override + public void setId(long id) { + this.id = id; + } + + @Override + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + + + public long getZoneId() { + return zoneId; + } + + public void setZoneId(long zoneId) { + this.zoneId = zoneId; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public String getZoneName() { + return zoneName; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProviderName() { + return providerName; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public ScopeType getScope() { + return scope; + } + + public void setScope(ScopeType scope) { + this.scope = scope; + } + + public long getRegionId() { + return regionId; + } + + public void setRegionId(long regionId) { + this.regionId = regionId; + } + + public String getRegionName() { + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + public void setName(String name) { + this.name = name; + } + + public String getDetailName() { + return detailName; + } + + public void setDetailName(String detailName) { + this.detailName = detailName; + } + + public String getDetailValue() { + return detailValue; + } + + public void setDetailValue(String detailValue) { + this.detailValue = detailValue; + } + + + +} diff --git a/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java b/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java new file mode 100644 index 00000000000..1b3fa46b042 --- /dev/null +++ b/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java @@ -0,0 +1,75 @@ +// 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.storage.dao; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; + +import org.apache.cloudstack.storage.datastore.db.ImageDataStoreDetailVO; +import org.apache.cloudstack.storage.datastore.db.ImageDataStoreDetailsDao; +import org.springframework.stereotype.Component; + +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; + +@Component +@Local(value=ImageDataStoreDetailsDao.class) +public class ImageDataStoreDaoImpl extends GenericDaoBase implements ImageDataStoreDetailsDao { + + protected final SearchBuilder storeSearch; + + protected ImageDataStoreDaoImpl() { + super(); + storeSearch = createSearchBuilder(); + storeSearch.and("store", storeSearch.entity().getStoreId(), SearchCriteria.Op.EQ); + storeSearch.done(); + } + + @Override + public void update(long storeId, Map details) { + Transaction txn = Transaction.currentTxn(); + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store", storeId); + + txn.start(); + expunge(sc); + for (Map.Entry entry : details.entrySet()) { + ImageDataStoreDetailVO detail = new ImageDataStoreDetailVO(storeId, entry.getKey(), entry.getValue()); + persist(detail); + } + txn.commit(); + } + + @Override + public Map getDetails(long storeId) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store", storeId); + + List details = listBy(sc); + Map detailsMap = new HashMap(); + for (ImageDataStoreDetailVO detail : details) { + detailsMap.put(detail.getName(), detail.getValue()); + } + + return detailsMap; + } +} diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index da5d5d5dcdb..ed954619f49 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -91,7 +91,33 @@ CREATE TABLE `cloud`.`image_data_store_details` ( INDEX `i_image_data_store__name__value`(`name`(128), `value`(128)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - +DROP VIEW IF EXISTS `cloud`.`image_data_store_view`; +CREATE VIEW `cloud`.`image_data_store_view` AS + select + image_data_store.id, + image_data_store.uuid, + image_data_store.name, + image_data_store.provider_name, + image_data_store.protocol, + image_data_store.url, + image_data_store.scope, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + region.id region_id, + region.name region_name, + image_data_store_details.name detail_name, + image_data_store_details.value detail_value + from + `cloud`.`image_data_store` + left join + `cloud`.`data_center` ON image_data_store.data_center_id = data_center.id + left join + `cloud`.`region` ON image_data_store.region_id = region.id + left join + `cloud`.`image_data_store_details` ON image_data_store_details.store_id = image_data_store.id; + + CREATE TABLE `cloud`.`template_store_ref` ( `id` bigint unsigned NOT NULL auto_increment, `store_id` bigint unsigned NOT NULL,