mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
ObjectStore Framework with MinIO and Simulator plugins (#7752)
This PR adds Object Storage feature to CloudStack. FS: https://cwiki.apache.org/confluence/display/CLOUDSTACK/%5BDRAFT%5D+CloudStack+Object+Store
This commit is contained in:
parent
37a2350159
commit
5651eab49c
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@ -93,6 +93,7 @@ jobs:
|
|||||||
smoke/test_nic
|
smoke/test_nic
|
||||||
smoke/test_nic_adapter_type
|
smoke/test_nic_adapter_type
|
||||||
smoke/test_non_contigiousvlan
|
smoke/test_non_contigiousvlan
|
||||||
|
smoke/test_object_stores
|
||||||
smoke/test_outofbandmanagement
|
smoke/test_outofbandmanagement
|
||||||
smoke/test_outofbandmanagement_nestedplugin
|
smoke/test_outofbandmanagement_nestedplugin
|
||||||
smoke/test_over_provisioning
|
smoke/test_over_provisioning
|
||||||
|
|||||||
@ -29,6 +29,8 @@ import org.apache.cloudstack.api.response.PodResponse;
|
|||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
import org.apache.cloudstack.config.Configuration;
|
import org.apache.cloudstack.config.Configuration;
|
||||||
import org.apache.cloudstack.ha.HAConfig;
|
import org.apache.cloudstack.ha.HAConfig;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
import org.apache.cloudstack.usage.Usage;
|
import org.apache.cloudstack.usage.Usage;
|
||||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||||
|
|
||||||
@ -714,6 +716,16 @@ public class EventTypes {
|
|||||||
// SystemVM
|
// SystemVM
|
||||||
public static final String EVENT_LIVE_PATCH_SYSTEMVM = "LIVE.PATCH.SYSTEM.VM";
|
public static final String EVENT_LIVE_PATCH_SYSTEMVM = "LIVE.PATCH.SYSTEM.VM";
|
||||||
|
|
||||||
|
// OBJECT STORE
|
||||||
|
public static final String EVENT_OBJECT_STORE_CREATE = "OBJECT.STORE.CREATE";
|
||||||
|
public static final String EVENT_OBJECT_STORE_DELETE = "OBJECT.STORE.DELETE";
|
||||||
|
public static final String EVENT_OBJECT_STORE_UPDATE = "OBJECT.STORE.UPDATE";
|
||||||
|
|
||||||
|
// BUCKETS
|
||||||
|
public static final String EVENT_BUCKET_CREATE = "BUCKET.CREATE";
|
||||||
|
public static final String EVENT_BUCKET_DELETE = "BUCKET.DELETE";
|
||||||
|
public static final String EVENT_BUCKET_UPDATE = "BUCKET.UPDATE";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
||||||
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
|
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
|
||||||
@ -1151,6 +1163,16 @@ public class EventTypes {
|
|||||||
entityEventDetails.put(EVENT_IMAGE_STORE_DATA_MIGRATE, ImageStore.class);
|
entityEventDetails.put(EVENT_IMAGE_STORE_DATA_MIGRATE, ImageStore.class);
|
||||||
entityEventDetails.put(EVENT_IMAGE_STORE_OBJECT_DOWNLOAD, ImageStore.class);
|
entityEventDetails.put(EVENT_IMAGE_STORE_OBJECT_DOWNLOAD, ImageStore.class);
|
||||||
entityEventDetails.put(EVENT_LIVE_PATCH_SYSTEMVM, "SystemVMs");
|
entityEventDetails.put(EVENT_LIVE_PATCH_SYSTEMVM, "SystemVMs");
|
||||||
|
|
||||||
|
//Object Store
|
||||||
|
entityEventDetails.put(EVENT_OBJECT_STORE_CREATE, ObjectStore.class);
|
||||||
|
entityEventDetails.put(EVENT_OBJECT_STORE_UPDATE, ObjectStore.class);
|
||||||
|
entityEventDetails.put(EVENT_OBJECT_STORE_DELETE, ObjectStore.class);
|
||||||
|
|
||||||
|
//Buckets
|
||||||
|
entityEventDetails.put(EVENT_BUCKET_CREATE, Bucket.class);
|
||||||
|
entityEventDetails.put(EVENT_BUCKET_UPDATE, Bucket.class);
|
||||||
|
entityEventDetails.put(EVENT_BUCKET_DELETE, Bucket.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getEntityForEvent(String eventName) {
|
public static String getEntityForEvent(String eventName) {
|
||||||
|
|||||||
@ -69,7 +69,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
|||||||
GuestOs(false, true),
|
GuestOs(false, true),
|
||||||
NetworkOffering(false, true),
|
NetworkOffering(false, true),
|
||||||
VpcOffering(true, false),
|
VpcOffering(true, false),
|
||||||
Domain(false, false, true);
|
Domain(false, false, true),
|
||||||
|
ObjectStore(false, false, true);
|
||||||
|
|
||||||
|
|
||||||
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) {
|
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ package com.cloud.storage;
|
|||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
public enum DataStoreRole {
|
public enum DataStoreRole {
|
||||||
Primary("primary"), Image("image"), ImageCache("imagecache"), Backup("backup");
|
Primary("primary"), Image("image"), ImageCache("imagecache"), Backup("backup"), Object("object");
|
||||||
|
|
||||||
public boolean isImageStore() {
|
public boolean isImageStore() {
|
||||||
return (role.equalsIgnoreCase("image") || role.equalsIgnoreCase("imagecache")) ? true : false;
|
return (role.equalsIgnoreCase("image") || role.equalsIgnoreCase("imagecache")) ? true : false;
|
||||||
@ -45,6 +45,8 @@ public enum DataStoreRole {
|
|||||||
return ImageCache;
|
return ImageCache;
|
||||||
} else if (role.equalsIgnoreCase("backup")) {
|
} else if (role.equalsIgnoreCase("backup")) {
|
||||||
return Backup;
|
return Backup;
|
||||||
|
} else if (role.equalsIgnoreCase("object")) {
|
||||||
|
return Object;
|
||||||
} else {
|
} else {
|
||||||
throw new CloudRuntimeException("can't identify the role");
|
throw new CloudRuntimeException("can't identify the role");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,9 +24,11 @@ import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaint
|
|||||||
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.DeleteObjectStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.UpdateObjectStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
||||||
|
|
||||||
import com.cloud.exception.DiscoveryException;
|
import com.cloud.exception.DiscoveryException;
|
||||||
@ -34,6 +36,7 @@ import com.cloud.exception.InsufficientCapacityException;
|
|||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.exception.ResourceInUseException;
|
import com.cloud.exception.ResourceInUseException;
|
||||||
import com.cloud.exception.ResourceUnavailableException;
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
|
|
||||||
public interface StorageService {
|
public interface StorageService {
|
||||||
/**
|
/**
|
||||||
@ -109,4 +112,9 @@ public interface StorageService {
|
|||||||
|
|
||||||
StoragePool syncStoragePool(SyncStoragePoolCmd cmd);
|
StoragePool syncStoragePool(SyncStoragePoolCmd cmd);
|
||||||
|
|
||||||
|
ObjectStore discoverObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
|
||||||
|
|
||||||
|
boolean deleteObjectStore(DeleteObjectStoragePoolCmd cmd);
|
||||||
|
|
||||||
|
ObjectStore updateObjectStore(Long id, UpdateObjectStoragePoolCmd cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public interface AnnotationService {
|
|||||||
SERVICE_OFFERING(false), DISK_OFFERING(false), NETWORK_OFFERING(false),
|
SERVICE_OFFERING(false), DISK_OFFERING(false), NETWORK_OFFERING(false),
|
||||||
ZONE(false), POD(false), CLUSTER(false), HOST(false), DOMAIN(false),
|
ZONE(false), POD(false), CLUSTER(false), HOST(false), DOMAIN(false),
|
||||||
PRIMARY_STORAGE(false), SECONDARY_STORAGE(false), VR(false), SYSTEM_VM(false),
|
PRIMARY_STORAGE(false), SECONDARY_STORAGE(false), VR(false), SYSTEM_VM(false),
|
||||||
AUTOSCALE_VM_GROUP(true), MANAGEMENT_SERVER(false),;
|
AUTOSCALE_VM_GROUP(true), MANAGEMENT_SERVER(false), OBJECT_STORAGE(false);
|
||||||
|
|
||||||
private final boolean usersAllowed;
|
private final boolean usersAllowed;
|
||||||
|
|
||||||
@ -78,6 +78,7 @@ public interface AnnotationService {
|
|||||||
list.add(EntityType.VR);
|
list.add(EntityType.VR);
|
||||||
list.add(EntityType.SYSTEM_VM);
|
list.add(EntityType.SYSTEM_VM);
|
||||||
list.add(EntityType.MANAGEMENT_SERVER);
|
list.add(EntityType.MANAGEMENT_SERVER);
|
||||||
|
list.add(EntityType.OBJECT_STORAGE);
|
||||||
if (roleType != RoleType.DomainAdmin) {
|
if (roleType != RoleType.DomainAdmin) {
|
||||||
list.add(EntityType.DOMAIN);
|
list.add(EntityType.DOMAIN);
|
||||||
list.add(EntityType.SERVICE_OFFERING);
|
list.add(EntityType.SERVICE_OFFERING);
|
||||||
|
|||||||
@ -78,7 +78,9 @@ public enum ApiCommandResourceType {
|
|||||||
VmSnapshot(com.cloud.vm.snapshot.VMSnapshot.class),
|
VmSnapshot(com.cloud.vm.snapshot.VMSnapshot.class),
|
||||||
Role(org.apache.cloudstack.acl.Role.class),
|
Role(org.apache.cloudstack.acl.Role.class),
|
||||||
VpnCustomerGateway(com.cloud.network.Site2SiteCustomerGateway.class),
|
VpnCustomerGateway(com.cloud.network.Site2SiteCustomerGateway.class),
|
||||||
ManagementServer(org.apache.cloudstack.management.ManagementServerHost.class);
|
ManagementServer(org.apache.cloudstack.management.ManagementServerHost.class),
|
||||||
|
ObjectStore(org.apache.cloudstack.storage.object.ObjectStore.class),
|
||||||
|
Bucket(org.apache.cloudstack.storage.object.Bucket.class);
|
||||||
|
|
||||||
private final Class<?> clazz;
|
private final Class<?> clazz;
|
||||||
|
|
||||||
|
|||||||
@ -1049,10 +1049,17 @@ public class ApiConstants {
|
|||||||
public static final String MTU = "mtu";
|
public static final String MTU = "mtu";
|
||||||
public static final String AUTO_ENABLE_KVM_HOST = "autoenablekvmhost";
|
public static final String AUTO_ENABLE_KVM_HOST = "autoenablekvmhost";
|
||||||
public static final String LIST_APIS = "listApis";
|
public static final String LIST_APIS = "listApis";
|
||||||
|
public static final String OBJECT_STORAGE_ID = "objectstorageid";
|
||||||
|
public static final String VERSIONING = "versioning";
|
||||||
|
public static final String OBJECT_LOCKING = "objectlocking";
|
||||||
|
public static final String ENCRYPTION = "encryption";
|
||||||
|
public static final String QUOTA = "quota";
|
||||||
|
public static final String ACCESS_KEY = "accesskey";
|
||||||
|
|
||||||
public static final String SOURCE_NAT_IP = "sourcenatipaddress";
|
public static final String SOURCE_NAT_IP = "sourcenatipaddress";
|
||||||
public static final String SOURCE_NAT_IP_ID = "sourcenatipaddressid";
|
public static final String SOURCE_NAT_IP_ID = "sourcenatipaddressid";
|
||||||
public static final String HAS_RULES = "hasrules";
|
public static final String HAS_RULES = "hasrules";
|
||||||
|
public static final String OBJECT_STORAGE = "objectstore";
|
||||||
|
|
||||||
public static final String MANAGEMENT = "management";
|
public static final String MANAGEMENT = "management";
|
||||||
public static final String IS_VNF = "isvnf";
|
public static final String IS_VNF = "isvnf";
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
|
|||||||
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
|
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
|
||||||
import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
|
import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
|
||||||
import org.apache.cloudstack.query.QueryService;
|
import org.apache.cloudstack.query.QueryService;
|
||||||
|
import org.apache.cloudstack.storage.object.BucketApiService;
|
||||||
import org.apache.cloudstack.storage.ImageStoreService;
|
import org.apache.cloudstack.storage.ImageStoreService;
|
||||||
import org.apache.cloudstack.storage.template.VnfTemplateManager;
|
import org.apache.cloudstack.storage.template.VnfTemplateManager;
|
||||||
import org.apache.cloudstack.usage.UsageService;
|
import org.apache.cloudstack.usage.UsageService;
|
||||||
@ -216,6 +217,9 @@ public abstract class BaseCmd {
|
|||||||
public Ipv6Service ipv6Service;
|
public Ipv6Service ipv6Service;
|
||||||
@Inject
|
@Inject
|
||||||
public VnfTemplateManager vnfTemplateManager;
|
public VnfTemplateManager vnfTemplateManager;
|
||||||
|
@Inject
|
||||||
|
public BucketApiService _bucketService;
|
||||||
|
|
||||||
|
|
||||||
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||||
ResourceAllocationException, NetworkRuleConflictException;
|
ResourceAllocationException, NetworkRuleConflictException;
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||||
import org.apache.cloudstack.api.ApiConstants.HostDetails;
|
import org.apache.cloudstack.api.ApiConstants.HostDetails;
|
||||||
@ -37,6 +38,7 @@ import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
|
|||||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||||
import org.apache.cloudstack.api.response.BackupResponse;
|
import org.apache.cloudstack.api.response.BackupResponse;
|
||||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
import org.apache.cloudstack.api.response.CapacityResponse;
|
import org.apache.cloudstack.api.response.CapacityResponse;
|
||||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||||
import org.apache.cloudstack.api.response.ConditionResponse;
|
import org.apache.cloudstack.api.response.ConditionResponse;
|
||||||
@ -82,6 +84,7 @@ import org.apache.cloudstack.api.response.NetworkPermissionsResponse;
|
|||||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||||
import org.apache.cloudstack.api.response.NicResponse;
|
import org.apache.cloudstack.api.response.NicResponse;
|
||||||
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
|
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.OvsProviderResponse;
|
import org.apache.cloudstack.api.response.OvsProviderResponse;
|
||||||
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
||||||
import org.apache.cloudstack.api.response.PodResponse;
|
import org.apache.cloudstack.api.response.PodResponse;
|
||||||
@ -145,6 +148,7 @@ import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
|
|||||||
import org.apache.cloudstack.region.PortableIp;
|
import org.apache.cloudstack.region.PortableIp;
|
||||||
import org.apache.cloudstack.region.PortableIpRange;
|
import org.apache.cloudstack.region.PortableIpRange;
|
||||||
import org.apache.cloudstack.region.Region;
|
import org.apache.cloudstack.region.Region;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
import org.apache.cloudstack.usage.Usage;
|
import org.apache.cloudstack.usage.Usage;
|
||||||
|
|
||||||
import com.cloud.capacity.Capacity;
|
import com.cloud.capacity.Capacity;
|
||||||
@ -533,4 +537,8 @@ public interface ResponseGenerator {
|
|||||||
FirewallResponse createIpv6FirewallRuleResponse(FirewallRule acl);
|
FirewallResponse createIpv6FirewallRuleResponse(FirewallRule acl);
|
||||||
|
|
||||||
IpQuarantineResponse createQuarantinedIpsResponse(PublicIpQuarantine publicIp);
|
IpQuarantineResponse createQuarantinedIpsResponse(PublicIpQuarantine publicIp);
|
||||||
|
|
||||||
|
ObjectStoreResponse createObjectStoreResponse(ObjectStore os);
|
||||||
|
|
||||||
|
BucketResponse createBucketResponse(Bucket bucket);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,132 @@
|
|||||||
|
// 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.api.command.admin.storage;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@APICommand(name = "addObjectStoragePool", description = "Adds a object storage pool", responseObject = ObjectStoreResponse.class, since = "4.19.0",
|
||||||
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
|
public class AddObjectStoragePoolCmd extends BaseCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(AddObjectStoragePoolCmd.class.getName());
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name for the object store")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, length = 2048, required = true, description = "the URL for the object store")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, required = true, description = "the object store provider name")
|
||||||
|
private String providerName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DETAILS,
|
||||||
|
type = CommandType.MAP,
|
||||||
|
description = "the details for the object store. Example: details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss")
|
||||||
|
private Map details;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for the storage pool")
|
||||||
|
private String tags;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getDetails() {
|
||||||
|
Map<String, String> detailsMap = null;
|
||||||
|
if (details != null && !details.isEmpty()) {
|
||||||
|
detailsMap = new HashMap<String, String>();
|
||||||
|
Collection<?> props = details.values();
|
||||||
|
Iterator<?> iter = props.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
HashMap<String, String> detail = (HashMap<String, String>)iter.next();
|
||||||
|
String key = detail.get(ApiConstants.KEY);
|
||||||
|
String value = detail.get(ApiConstants.VALUE);
|
||||||
|
detailsMap.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return detailsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderName() {
|
||||||
|
return providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderName(String providerName) {
|
||||||
|
this.providerName = providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDetails(Map<String, String> details) {
|
||||||
|
this.details = details;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
return Account.ACCOUNT_ID_SYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(){
|
||||||
|
try{
|
||||||
|
ObjectStore result = _storageService.discoverObjectStore(getName(), getUrl(), getProviderName(), getDetails());
|
||||||
|
ObjectStoreResponse storeResponse = null;
|
||||||
|
if (result != null) {
|
||||||
|
storeResponse = _responseGenerator.createObjectStoreResponse(result);
|
||||||
|
storeResponse.setResponseName(getCommandName());
|
||||||
|
storeResponse.setObjectName("objectstore");
|
||||||
|
setResponseObject(storeResponse);
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add object storage");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
s_logger.error("Exception: ", ex);
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
// 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.api.command.admin.storage;
|
||||||
|
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@APICommand(name = "deleteObjectStoragePool", description = "Deletes an Object Storage Pool", responseObject = SuccessResponse.class, since = "4.19.0",
|
||||||
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
|
public class DeleteObjectStoragePoolCmd extends BaseCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(DeleteObjectStoragePoolCmd.class.getName());
|
||||||
|
|
||||||
|
// ///////////////////////////////////////////////////
|
||||||
|
// ////////////// API parameters /////////////////////
|
||||||
|
// ///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ObjectStoreResponse.class, required = true, description = "The Object Storage ID.")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
// ///////////////////////////////////////////////////
|
||||||
|
// ///////////////// Accessors ///////////////////////
|
||||||
|
// ///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ///////////////////////////////////////////////////
|
||||||
|
// ///////////// API Implementation///////////////////
|
||||||
|
// ///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
return Account.ACCOUNT_ID_SYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
boolean result = _storageService.deleteObjectStore(this);
|
||||||
|
if (result) {
|
||||||
|
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||||
|
this.setResponseObject(response);
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete object store");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
// 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.api.command.admin.storage;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseListCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@APICommand(name = "listObjectStoragePools", description = "Lists object storage pools.", responseObject = ObjectStoreResponse.class, since = "4.19.0",
|
||||||
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||||
|
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||||
|
public class ListObjectStoragePoolsCmd extends BaseListCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(ListObjectStoragePoolsCmd.class.getName());
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the object store")
|
||||||
|
private String storeName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, description = "the object store provider")
|
||||||
|
private String provider;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ObjectStoreResponse.class, description = "the ID of the storage pool")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
public String getStoreName() {
|
||||||
|
return storeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProvider(String provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
ListResponse<ObjectStoreResponse> response = _queryService.searchForObjectStores(this);
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
this.setResponseObject(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
// 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.api.command.admin.storage;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
|
||||||
|
@APICommand(name = UpdateObjectStoragePoolCmd.APINAME, description = "Updates object storage pool", responseObject = ObjectStoreResponse.class, entityType = {ObjectStore.class},
|
||||||
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0")
|
||||||
|
public class UpdateObjectStoragePoolCmd extends BaseCmd {
|
||||||
|
public static final String APINAME = "updateObjectStoragePool";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ObjectStoreResponse.class, required = true, description = "Object Store ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name for the object store")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, description = "the url for the object store")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
ObjectStore result = _storageService.updateObjectStore(getId(), this);
|
||||||
|
|
||||||
|
ObjectStoreResponse storeResponse = null;
|
||||||
|
if (result != null) {
|
||||||
|
storeResponse = _responseGenerator.createObjectStoreResponse(result);
|
||||||
|
storeResponse.setResponseName(getCommandName());
|
||||||
|
storeResponse.setObjectName("objectstore");
|
||||||
|
setResponseObject(storeResponse);
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update object storage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return APINAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
return CallContext.current().getCallingAccountId();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,202 @@
|
|||||||
|
// 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.api.command.user.bucket;
|
||||||
|
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@APICommand(name = "createBucket", responseObject = BucketResponse.class,
|
||||||
|
description = "Creates a bucket in the specified object storage pool. ", responseView = ResponseView.Restricted,
|
||||||
|
entityType = {Bucket.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||||
|
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||||
|
public class CreateBucketCmd extends BaseAsyncCreateCmd implements UserCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(CreateBucketCmd.class.getName());
|
||||||
|
private static final String s_name = "createbucketresponse";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ACCOUNT,
|
||||||
|
type = CommandType.STRING,
|
||||||
|
description = "the account associated with the bucket. Must be used with the domainId parameter.")
|
||||||
|
private String accountName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.PROJECT_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = ProjectResponse.class,
|
||||||
|
description = "the project associated with the bucket. Mutually exclusive with account parameter")
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = DomainResponse.class,
|
||||||
|
description = "the domain ID associated with the bucket. If used with the account parameter"
|
||||||
|
+ " returns the bucket associated with the account for the specified domain.")
|
||||||
|
private Long domainId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true,description = "the name of the bucket")
|
||||||
|
private String bucketName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.OBJECT_STORAGE_ID, type = CommandType.UUID,
|
||||||
|
entityType = ObjectStoreResponse.class, required = true,
|
||||||
|
description = "Id of the Object Storage Pool where bucket is created")
|
||||||
|
private long objectStoragePoolId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER,description = "Bucket Quota in GB")
|
||||||
|
private Integer quota;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ENCRYPTION, type = CommandType.BOOLEAN, description = "Enable bucket encryption")
|
||||||
|
private boolean encryption;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.VERSIONING, type = CommandType.BOOLEAN, description = "Enable bucket versioning")
|
||||||
|
private boolean versioning;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.OBJECT_LOCKING, type = CommandType.BOOLEAN, description = "Enable object locking in bucket")
|
||||||
|
private boolean objectLocking;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.POLICY, type = CommandType.STRING,description = "The Bucket access policy")
|
||||||
|
private String policy;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public String getAccountName() {
|
||||||
|
return accountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBucketName() {
|
||||||
|
return bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getProjectId() {
|
||||||
|
return projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getObjectStoragePoolId() {
|
||||||
|
return objectStoragePoolId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getQuota() {
|
||||||
|
return quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEncryption() {
|
||||||
|
return encryption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVersioning() {
|
||||||
|
return versioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isObjectLocking() {
|
||||||
|
return objectLocking;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPolicy() {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return s_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getResultObjectName() {
|
||||||
|
return "bucket";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiCommandResourceType getApiResourceType() {
|
||||||
|
return ApiCommandResourceType.Bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
|
||||||
|
if (accountId == null) {
|
||||||
|
return CallContext.current().getCallingAccount().getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventType() {
|
||||||
|
return EventTypes.EVENT_BUCKET_CREATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventDescription() {
|
||||||
|
return "creating bucket: " + getBucketName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() throws ResourceAllocationException {
|
||||||
|
Bucket bucket = _bucketService.allocBucket(this);
|
||||||
|
if (bucket != null) {
|
||||||
|
setEntityId(bucket.getId());
|
||||||
|
setEntityUuid(bucket.getUuid());
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create bucket");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
CallContext.current().setEventDetails("Bucket Id: " + getEntityUuid());
|
||||||
|
|
||||||
|
Bucket bucket;
|
||||||
|
try {
|
||||||
|
bucket = _bucketService.createBucket(this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
if (bucket != null) {
|
||||||
|
BucketResponse response = _responseGenerator.createBucketResponse(bucket);
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
setResponseObject(response);
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create bucket with name: "+getBucketName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
// 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.api.command.user.bucket;
|
||||||
|
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
|
import org.apache.cloudstack.api.ACL;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
|
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@APICommand(name = "deleteBucket", description = "Deletes an empty Bucket.", responseObject = SuccessResponse.class, entityType = {Bucket.class},
|
||||||
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||||
|
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||||
|
public class DeleteBucketCmd extends BaseCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(DeleteBucketCmd.class.getName());
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ACL(accessType = AccessType.OperateEntry)
|
||||||
|
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=BucketResponse.class,
|
||||||
|
required=true, description="The ID of the Bucket")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public static String getResultObjectName() {
|
||||||
|
return "bucket";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
Bucket Bucket = _entityMgr.findById(Bucket.class, getId());
|
||||||
|
if (Bucket != null) {
|
||||||
|
return Bucket.getAccountId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getApiResourceId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiCommandResourceType getApiResourceType() {
|
||||||
|
return ApiCommandResourceType.Bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws ConcurrentOperationException {
|
||||||
|
CallContext.current().setEventDetails("Bucket Id: " + this._uuidMgr.getUuid(Bucket.class, getId()));
|
||||||
|
boolean result = _bucketService.deleteBucket(id, CallContext.current().getCallingAccount());
|
||||||
|
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||||
|
response.setSuccess(result);
|
||||||
|
setResponseObject(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
// 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.api.command.user.bucket;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||||
|
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@APICommand(name = "listBuckets", description = "Lists all Buckets.", responseObject = BucketResponse.class, responseView = ResponseView.Restricted, entityType = {
|
||||||
|
Bucket.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||||
|
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||||
|
public class ListBucketsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(ListBucketsCmd.class.getName());
|
||||||
|
|
||||||
|
private static final String s_name = "listbucketsresponse";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = BucketResponse.class, description = "the ID of the bucket")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = BucketResponse.class, description = "the IDs of the Buckets, mutually exclusive with id")
|
||||||
|
private List<Long> ids;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the bucket")
|
||||||
|
private String bucketName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.OBJECT_STORAGE_ID, type = CommandType.UUID, entityType = StoragePoolResponse.class, description = "the ID of the object storage pool, available to ROOT admin only", authorized = {
|
||||||
|
RoleType.Admin})
|
||||||
|
private Long objectStorageId;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBucketName() {
|
||||||
|
return bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getObjectStorageId() {
|
||||||
|
return objectStorageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return s_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiCommandResourceType getApiResourceType() {
|
||||||
|
return ApiCommandResourceType.Bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
ListResponse<BucketResponse> response = _queryService.searchForBuckets(this);
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
setResponseObject(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> getIds() {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
// 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.api.command.user.bucket;
|
||||||
|
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
|
import org.apache.cloudstack.api.ACL;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
|
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@APICommand(name = "updateBucket", description = "Updates Bucket properties", responseObject = SuccessResponse.class, entityType = {Bucket.class},
|
||||||
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
|
||||||
|
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||||
|
public class UpdateBucketCmd extends BaseCmd {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(UpdateBucketCmd.class.getName());
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ACL(accessType = AccessType.OperateEntry)
|
||||||
|
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=BucketResponse.class,
|
||||||
|
required=true, description="The ID of the Bucket")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.VERSIONING, type = CommandType.BOOLEAN, description = "Enable/Disable Bucket Versioning")
|
||||||
|
private Boolean versioning;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ENCRYPTION, type = CommandType.BOOLEAN, description = "Enable/Disable Bucket encryption")
|
||||||
|
private Boolean encryption;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.POLICY, type = CommandType.STRING, description = "Bucket Access Policy")
|
||||||
|
private String policy;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER,description = "Bucket Quota in GB")
|
||||||
|
private Integer quota;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getVersioning() {
|
||||||
|
return versioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEncryption() {
|
||||||
|
return encryption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPolicy() {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getQuota() {
|
||||||
|
return quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////// API Implementation///////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public static String getResultObjectName() {
|
||||||
|
return "bucket";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
Bucket Bucket = _entityMgr.findById(Bucket.class, getId());
|
||||||
|
if (Bucket != null) {
|
||||||
|
return Bucket.getAccountId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getApiResourceId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiCommandResourceType getApiResourceType() {
|
||||||
|
return ApiCommandResourceType.Bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws ConcurrentOperationException {
|
||||||
|
CallContext.current().setEventDetails("Bucket Id: " + this._uuidMgr.getUuid(Bucket.class, getId()));
|
||||||
|
boolean result = false;
|
||||||
|
try {
|
||||||
|
result = _bucketService.updateBucket(this, CallContext.current().getCallingAccount());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Error while updating bucket. "+e.getMessage());
|
||||||
|
}
|
||||||
|
if(result) {
|
||||||
|
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||||
|
setResponseObject(response);
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update bucket");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,293 @@
|
|||||||
|
// 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.api.response;
|
||||||
|
|
||||||
|
import com.cloud.serializer.Param;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
|
||||||
|
import org.apache.cloudstack.api.EntityReference;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@EntityReference(value = Bucket.class)
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class BucketResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse, ControlledEntityResponse {
|
||||||
|
@SerializedName(ApiConstants.ID)
|
||||||
|
@Param(description = "ID of the Bucket")
|
||||||
|
private String id;
|
||||||
|
@SerializedName(ApiConstants.NAME)
|
||||||
|
@Param(description = "name of the Bucket")
|
||||||
|
private String name;
|
||||||
|
@SerializedName(ApiConstants.CREATED)
|
||||||
|
@Param(description = "the date the Bucket was created")
|
||||||
|
private Date created;
|
||||||
|
@SerializedName(ApiConstants.ACCOUNT)
|
||||||
|
@Param(description = "the account associated with the Bucket")
|
||||||
|
private String accountName;
|
||||||
|
@SerializedName(ApiConstants.PROJECT_ID)
|
||||||
|
@Param(description = "the project id of the bucket")
|
||||||
|
private String projectId;
|
||||||
|
@SerializedName(ApiConstants.PROJECT)
|
||||||
|
@Param(description = "the project name of the bucket")
|
||||||
|
private String projectName;
|
||||||
|
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||||
|
@Param(description = "the ID of the domain associated with the bucket")
|
||||||
|
private String domainId;
|
||||||
|
@SerializedName(ApiConstants.DOMAIN)
|
||||||
|
@Param(description = "the domain associated with the bucket")
|
||||||
|
private String domainName;
|
||||||
|
@SerializedName(ApiConstants.OBJECT_STORAGE_ID)
|
||||||
|
@Param(description = "id of the object storage hosting the Bucket; returned to admin user only")
|
||||||
|
private String objectStoragePoolId;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.OBJECT_STORAGE)
|
||||||
|
@Param(description = "Name of the object storage hosting the Bucket; returned to admin user only")
|
||||||
|
private String objectStoragePool;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.SIZE)
|
||||||
|
@Param(description = "Total size of objects in Bucket")
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.STATE)
|
||||||
|
@Param(description = "State of the Bucket")
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.QUOTA)
|
||||||
|
@Param(description = "Bucket Quota in GB")
|
||||||
|
private Integer quota;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.ENCRYPTION)
|
||||||
|
@Param(description = "Bucket Encryption")
|
||||||
|
private Boolean encryption;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.VERSIONING)
|
||||||
|
@Param(description = "Bucket Versioning")
|
||||||
|
private Boolean versioning;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.OBJECT_LOCKING)
|
||||||
|
@Param(description = "Bucket Object Locking")
|
||||||
|
private Boolean objectLock;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.POLICY)
|
||||||
|
@Param(description = "Bucket Access Policy")
|
||||||
|
private String policy;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.URL)
|
||||||
|
@Param(description = "Bucket URL")
|
||||||
|
private String bucketURL;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.ACCESS_KEY)
|
||||||
|
@Param(description = "Bucket Access Key")
|
||||||
|
private String accessKey;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.SECRET_KEY)
|
||||||
|
@Param(description = "Bucket Secret Key")
|
||||||
|
private String secretKey;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.PROVIDER)
|
||||||
|
@Param(description = "Object storage provider")
|
||||||
|
private String provider;
|
||||||
|
|
||||||
|
public BucketResponse() {
|
||||||
|
tags = new LinkedHashSet<ResourceTagResponse>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjectId() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreated(Date created) {
|
||||||
|
this.created = created;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAccountName(String accountName) {
|
||||||
|
this.accountName = accountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDomainId(String domainId) {
|
||||||
|
this.domainId = domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDomainName(String domainName) {
|
||||||
|
this.domainName = domainName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProjectId(String projectId) {
|
||||||
|
this.projectId = projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProjectName(String projectName) {
|
||||||
|
this.projectName = projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTags(Set<ResourceTagResponse> tags) {
|
||||||
|
this.tags = tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObjectStoragePoolId(String objectStoragePoolId) {
|
||||||
|
this.objectStoragePoolId = objectStoragePoolId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountName() {
|
||||||
|
return accountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProjectId() {
|
||||||
|
return projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProjectName() {
|
||||||
|
return projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomainName() {
|
||||||
|
return domainName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getObjectStoragePoolId() {
|
||||||
|
return objectStoragePoolId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
public long getQuota() {
|
||||||
|
return quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuota(Integer quota) {
|
||||||
|
this.quota = quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVersioning() {
|
||||||
|
return versioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersioning(boolean versioning) {
|
||||||
|
this.versioning = versioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEncryption() {
|
||||||
|
return encryption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncryption(boolean encryption) {
|
||||||
|
this.encryption = encryption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isObjectLock() {
|
||||||
|
return objectLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObjectLock(boolean objectLock) {
|
||||||
|
this.objectLock = objectLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPolicy() {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolicy(String policy) {
|
||||||
|
this.policy = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBucketURL() {
|
||||||
|
return bucketURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBucketURL(String bucketURL) {
|
||||||
|
this.bucketURL = bucketURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessKey() {
|
||||||
|
return accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessKey(String accessKey) {
|
||||||
|
this.accessKey = accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecretKey() {
|
||||||
|
return secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecretKey(String secretKey) {
|
||||||
|
this.secretKey = secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(Bucket.State state) {
|
||||||
|
this.state = state.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObjectStoragePool(String objectStoragePool) {
|
||||||
|
this.objectStoragePool = objectStoragePool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getObjectStoragePool() {
|
||||||
|
return objectStoragePool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProvider(String provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
// 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.api.response;
|
||||||
|
|
||||||
|
import com.cloud.serializer.Param;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import org.apache.cloudstack.api.BaseResponseWithAnnotations;
|
||||||
|
import org.apache.cloudstack.api.EntityReference;
|
||||||
|
|
||||||
|
@EntityReference(value = ObjectStore.class)
|
||||||
|
public class ObjectStoreResponse extends BaseResponseWithAnnotations {
|
||||||
|
@SerializedName("id")
|
||||||
|
@Param(description = "the ID of the object store")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@SerializedName("name")
|
||||||
|
@Param(description = "the name of the object store")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@SerializedName("url")
|
||||||
|
@Param(description = "the url of the object store")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@SerializedName("providername")
|
||||||
|
@Param(description = "the provider name of the object store")
|
||||||
|
private String providerName;
|
||||||
|
|
||||||
|
@SerializedName("storagetotal")
|
||||||
|
@Param(description = "the total size of the object store")
|
||||||
|
private Long storageTotal;
|
||||||
|
|
||||||
|
@SerializedName("storageused")
|
||||||
|
@Param(description = "the object store currently used size")
|
||||||
|
private Long storageUsed;
|
||||||
|
|
||||||
|
public ObjectStoreResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjectId() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderName() {
|
||||||
|
return providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderName(String providerName) {
|
||||||
|
this.providerName = providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getStorageTotal() {
|
||||||
|
return storageTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStorageTotal(Long storageTotal) {
|
||||||
|
this.storageTotal = storageTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getStorageUsed() {
|
||||||
|
return storageUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStorageUsed(Long storageUsed) {
|
||||||
|
this.storageUsed = storageUsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -28,6 +28,7 @@ import org.apache.cloudstack.api.command.admin.resource.icon.ListResourceIconCmd
|
|||||||
import org.apache.cloudstack.api.command.admin.router.GetRouterHealthCheckResultsCmd;
|
import org.apache.cloudstack.api.command.admin.router.GetRouterHealthCheckResultsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
|
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.ListObjectStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
|
||||||
@ -36,6 +37,7 @@ import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
|
|||||||
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
|
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.address.ListQuarantinedIpsCmd;
|
import org.apache.cloudstack.api.command.user.address.ListQuarantinedIpsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
|
import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.ListBucketsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
|
import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
|
||||||
import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
|
import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
|
||||||
@ -56,6 +58,7 @@ import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
|
|||||||
import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
|
import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
|
||||||
import org.apache.cloudstack.api.response.AccountResponse;
|
import org.apache.cloudstack.api.response.AccountResponse;
|
||||||
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
import org.apache.cloudstack.api.response.DetailOptionsResponse;
|
import org.apache.cloudstack.api.response.DetailOptionsResponse;
|
||||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||||
import org.apache.cloudstack.api.response.DomainResponse;
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
@ -68,6 +71,7 @@ import org.apache.cloudstack.api.response.InstanceGroupResponse;
|
|||||||
import org.apache.cloudstack.api.response.IpQuarantineResponse;
|
import org.apache.cloudstack.api.response.IpQuarantineResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
import org.apache.cloudstack.api.response.ManagementServerResponse;
|
import org.apache.cloudstack.api.response.ManagementServerResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||||
@ -190,4 +194,8 @@ public interface QueryService {
|
|||||||
ListResponse<SnapshotResponse> listSnapshots(ListSnapshotsCmd cmd);
|
ListResponse<SnapshotResponse> listSnapshots(ListSnapshotsCmd cmd);
|
||||||
|
|
||||||
SnapshotResponse listSnapshot(CopySnapshotCmd cmd);
|
SnapshotResponse listSnapshot(CopySnapshotCmd cmd);
|
||||||
|
|
||||||
|
ListResponse<ObjectStoreResponse> searchForObjectStores(ListObjectStoragePoolsCmd listObjectStoragePoolsCmd);
|
||||||
|
|
||||||
|
ListResponse<BucketResponse> searchForBuckets(ListBucketsCmd listBucketsCmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
// 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.object;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
|
import org.apache.cloudstack.api.Identity;
|
||||||
|
import org.apache.cloudstack.api.InternalIdentity;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public interface Bucket extends ControlledEntity, Identity, InternalIdentity {
|
||||||
|
|
||||||
|
long getObjectStoreId();
|
||||||
|
|
||||||
|
Date getCreated();
|
||||||
|
|
||||||
|
State getState();
|
||||||
|
|
||||||
|
void setName(String name);
|
||||||
|
|
||||||
|
Long getSize();
|
||||||
|
|
||||||
|
Integer getQuota();
|
||||||
|
|
||||||
|
boolean isVersioning();
|
||||||
|
|
||||||
|
boolean isEncryption();
|
||||||
|
|
||||||
|
boolean isObjectLock();
|
||||||
|
|
||||||
|
String getPolicy();
|
||||||
|
|
||||||
|
String getBucketURL();
|
||||||
|
|
||||||
|
String getAccessKey();
|
||||||
|
|
||||||
|
String getSecretKey();
|
||||||
|
|
||||||
|
public enum State {
|
||||||
|
Allocated, Created, Destroyed;
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(String status) {
|
||||||
|
return this.toString().equalsIgnoreCase(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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.object;
|
||||||
|
|
||||||
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.CreateBucketCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.UpdateBucketCmd;
|
||||||
|
|
||||||
|
public interface BucketApiService {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the database object for a Bucket based on the given criteria
|
||||||
|
*
|
||||||
|
* @param cmd
|
||||||
|
* the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
|
||||||
|
* name)
|
||||||
|
* @return the Bucket object
|
||||||
|
*/
|
||||||
|
Bucket allocBucket(CreateBucketCmd cmd) throws ResourceAllocationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the Bucket based on the given criteria
|
||||||
|
*
|
||||||
|
* @param cmd
|
||||||
|
* the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
|
||||||
|
* name)
|
||||||
|
* @return the Bucket object
|
||||||
|
*/
|
||||||
|
Bucket createBucket(CreateBucketCmd cmd);
|
||||||
|
|
||||||
|
boolean deleteBucket(long bucketId, Account caller);
|
||||||
|
|
||||||
|
boolean updateBucket(UpdateBucketCmd cmd, Account caller);
|
||||||
|
|
||||||
|
void getBucketUsage();
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
// 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.object;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.Identity;
|
||||||
|
import org.apache.cloudstack.api.InternalIdentity;
|
||||||
|
|
||||||
|
public interface ObjectStore extends Identity, InternalIdentity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return name of the object store.
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return object store provider name
|
||||||
|
*/
|
||||||
|
String getProviderName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return uri
|
||||||
|
*/
|
||||||
|
String getUrl();
|
||||||
|
|
||||||
|
}
|
||||||
@ -45,6 +45,7 @@ public class UsageTypes {
|
|||||||
public static final int VOLUME_SECONDARY = 26;
|
public static final int VOLUME_SECONDARY = 26;
|
||||||
public static final int VM_SNAPSHOT_ON_PRIMARY = 27;
|
public static final int VM_SNAPSHOT_ON_PRIMARY = 27;
|
||||||
public static final int BACKUP = 28;
|
public static final int BACKUP = 28;
|
||||||
|
public static final int BUCKET = 29;
|
||||||
|
|
||||||
public static List<UsageTypeResponse> listUsageTypes() {
|
public static List<UsageTypeResponse> listUsageTypes() {
|
||||||
List<UsageTypeResponse> responseList = new ArrayList<UsageTypeResponse>();
|
List<UsageTypeResponse> responseList = new ArrayList<UsageTypeResponse>();
|
||||||
@ -70,6 +71,7 @@ public class UsageTypes {
|
|||||||
responseList.add(new UsageTypeResponse(VOLUME_SECONDARY, "Volume on secondary storage usage"));
|
responseList.add(new UsageTypeResponse(VOLUME_SECONDARY, "Volume on secondary storage usage"));
|
||||||
responseList.add(new UsageTypeResponse(VM_SNAPSHOT_ON_PRIMARY, "VM Snapshot on primary storage usage"));
|
responseList.add(new UsageTypeResponse(VM_SNAPSHOT_ON_PRIMARY, "VM Snapshot on primary storage usage"));
|
||||||
responseList.add(new UsageTypeResponse(BACKUP, "Backup storage usage"));
|
responseList.add(new UsageTypeResponse(BACKUP, "Backup storage usage"));
|
||||||
|
responseList.add(new UsageTypeResponse(BUCKET, "Bucket storage usage"));
|
||||||
return responseList;
|
return responseList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.command.admin.storage;
|
||||||
|
|
||||||
|
import com.cloud.exception.DiscoveryException;
|
||||||
|
import com.cloud.storage.StorageService;
|
||||||
|
import org.apache.cloudstack.api.ResponseGenerator;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyObject;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class AddObjectStoragePoolCmdTest {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(AddObjectStoragePoolCmdTest.class.getName());
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
StorageService storageService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStore objectStore;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ResponseGenerator responseGenerator;
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
AddObjectStoragePoolCmd addObjectStoragePoolCmdSpy;
|
||||||
|
|
||||||
|
String name = "testObjStore";
|
||||||
|
|
||||||
|
String url = "testURL";
|
||||||
|
|
||||||
|
String provider = "Simulator";
|
||||||
|
|
||||||
|
Map<String, String> details;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
details = new HashMap<>();
|
||||||
|
addObjectStoragePoolCmdSpy = Mockito.spy(new AddObjectStoragePoolCmd());
|
||||||
|
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "name", name);
|
||||||
|
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "url", url);
|
||||||
|
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "providerName", provider);
|
||||||
|
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "details", details);
|
||||||
|
addObjectStoragePoolCmdSpy._storageService = storageService;
|
||||||
|
addObjectStoragePoolCmdSpy._responseGenerator = responseGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
CallContext.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddObjectStore() throws DiscoveryException {
|
||||||
|
Mockito.doReturn(objectStore).when(storageService).discoverObjectStore(Mockito.anyString(),
|
||||||
|
Mockito.anyString(), Mockito.anyString(), anyObject());
|
||||||
|
ObjectStoreResponse objectStoreResponse = new ObjectStoreResponse();
|
||||||
|
Mockito.doReturn(objectStoreResponse).when(responseGenerator).createObjectStoreResponse(anyObject());
|
||||||
|
addObjectStoragePoolCmdSpy.execute();
|
||||||
|
|
||||||
|
Mockito.verify(storageService, Mockito.times(1))
|
||||||
|
.discoverObjectStore(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
* 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.api.command.admin.storage;
|
||||||
|
|
||||||
|
import com.cloud.storage.StorageService;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
|
||||||
|
public class DeleteObjectStoragePoolCmdTest {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(DeleteObjectStoragePoolCmdTest.class.getName());
|
||||||
|
@Mock
|
||||||
|
private StorageService storageService;
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
DeleteObjectStoragePoolCmd deleteObjectStoragePoolCmd;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
deleteObjectStoragePoolCmd = Mockito.spy(new DeleteObjectStoragePoolCmd());
|
||||||
|
deleteObjectStoragePoolCmd._storageService = storageService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
CallContext.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteObjectStore() {
|
||||||
|
Mockito.doReturn(true).when(storageService).deleteObjectStore(deleteObjectStoragePoolCmd);
|
||||||
|
deleteObjectStoragePoolCmd.execute();
|
||||||
|
Mockito.verify(storageService, Mockito.times(1))
|
||||||
|
.deleteObjectStore(deleteObjectStoragePoolCmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.command.admin.storage;
|
||||||
|
|
||||||
|
import com.cloud.storage.StorageService;
|
||||||
|
import org.apache.cloudstack.api.ResponseGenerator;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyObject;
|
||||||
|
|
||||||
|
public class UpdateObjectStoragePoolCmdTest {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(UpdateObjectStoragePoolCmdTest.class.getName());
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private StorageService storageService;
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
UpdateObjectStoragePoolCmd updateObjectStoragePoolCmd;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStore objectStore;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ResponseGenerator responseGenerator;
|
||||||
|
|
||||||
|
private String name = "testObjStore";
|
||||||
|
|
||||||
|
private String url = "testURL";
|
||||||
|
|
||||||
|
private String provider = "Simulator";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
updateObjectStoragePoolCmd = Mockito.spy(new UpdateObjectStoragePoolCmd());
|
||||||
|
updateObjectStoragePoolCmd._storageService = storageService;
|
||||||
|
updateObjectStoragePoolCmd._responseGenerator = responseGenerator;
|
||||||
|
ReflectionTestUtils.setField(updateObjectStoragePoolCmd, "name", name);
|
||||||
|
ReflectionTestUtils.setField(updateObjectStoragePoolCmd, "url", url);
|
||||||
|
ReflectionTestUtils.setField(updateObjectStoragePoolCmd, "id", 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
CallContext.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateObjectStore() {
|
||||||
|
Mockito.doReturn(objectStore).when(storageService).updateObjectStore(1L, updateObjectStoragePoolCmd);
|
||||||
|
ObjectStoreResponse objectStoreResponse = new ObjectStoreResponse();
|
||||||
|
Mockito.doReturn(objectStoreResponse).when(responseGenerator).createObjectStoreResponse(anyObject());
|
||||||
|
updateObjectStoragePoolCmd.execute();
|
||||||
|
Mockito.verify(storageService, Mockito.times(1))
|
||||||
|
.updateObjectStore(1L, updateObjectStoragePoolCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -577,6 +577,21 @@
|
|||||||
<artifactId>cloud-plugin-shutdown</artifactId>
|
<artifactId>cloud-plugin-shutdown</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage-object</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-plugin-storage-object-minio</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-plugin-storage-object-simulator</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|||||||
@ -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
|
||||||
|
* 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.engine.subsystem.api.storage;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
|
||||||
|
public interface BucketInfo extends DataObject, Bucket {
|
||||||
|
|
||||||
|
void addPayload(Object data);
|
||||||
|
|
||||||
|
Object getPayload();
|
||||||
|
|
||||||
|
Bucket getBucket();
|
||||||
|
}
|
||||||
@ -31,7 +31,7 @@ public interface DataStoreProvider {
|
|||||||
String DEFAULT_PRIMARY = "DefaultPrimary";
|
String DEFAULT_PRIMARY = "DefaultPrimary";
|
||||||
|
|
||||||
enum DataStoreProviderType {
|
enum DataStoreProviderType {
|
||||||
PRIMARY, IMAGE, ImageCache
|
PRIMARY, IMAGE, ImageCache, OBJECT
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStoreLifeCycle getDataStoreLifeCycle();
|
DataStoreLifeCycle getDataStoreLifeCycle();
|
||||||
|
|||||||
@ -33,4 +33,6 @@ public interface DataStoreProviderManager extends Manager, DataStoreProviderApiS
|
|||||||
DataStoreProvider getDefaultCacheDataStoreProvider();
|
DataStoreProvider getDefaultCacheDataStoreProvider();
|
||||||
|
|
||||||
List<DataStoreProvider> getProviders();
|
List<DataStoreProvider> getProviders();
|
||||||
|
|
||||||
|
DataStoreProvider getDefaultObjectStoreProvider();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
// 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.engine.subsystem.api.storage;
|
||||||
|
|
||||||
|
public interface ObjectStorageService {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.engine.subsystem.api.storage;
|
||||||
|
|
||||||
|
public interface ObjectStoreProvider extends DataStoreProvider {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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.object;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface ObjectStoreEntity extends DataStore, ObjectStore {
|
||||||
|
Bucket createBucket(Bucket bucket, boolean objectLock);
|
||||||
|
|
||||||
|
List<Bucket> listBuckets();
|
||||||
|
|
||||||
|
boolean createUser(long accountId);
|
||||||
|
|
||||||
|
boolean deleteBucket(String name);
|
||||||
|
|
||||||
|
boolean setBucketEncryption(String name);
|
||||||
|
|
||||||
|
boolean deleteBucketEncryption(String name);
|
||||||
|
|
||||||
|
boolean setBucketVersioning(String name);
|
||||||
|
|
||||||
|
boolean deleteBucketVersioning(String name);
|
||||||
|
|
||||||
|
void setBucketPolicy(String name, String policy);
|
||||||
|
|
||||||
|
void setQuota(String name, int quota);
|
||||||
|
|
||||||
|
Map<String, Long> getAllBucketsUsage();
|
||||||
|
}
|
||||||
@ -55,6 +55,7 @@
|
|||||||
<module>storage/configdrive</module>
|
<module>storage/configdrive</module>
|
||||||
<module>storage/datamotion</module>
|
<module>storage/datamotion</module>
|
||||||
<module>storage/image</module>
|
<module>storage/image</module>
|
||||||
|
<module>storage/object</module>
|
||||||
<module>storage/snapshot</module>
|
<module>storage/snapshot</module>
|
||||||
<module>storage/volume</module>
|
<module>storage/volume</module>
|
||||||
<module>userdata/cloud-init</module>
|
<module>userdata/cloud-init</module>
|
||||||
|
|||||||
257
engine/schema/src/main/java/com/cloud/storage/BucketVO.java
Normal file
257
engine/schema/src/main/java/com/cloud/storage/BucketVO.java
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
// 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;
|
||||||
|
|
||||||
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "bucket")
|
||||||
|
public class BucketVO implements Bucket {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(name = "id")
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
@Column(name = "account_id")
|
||||||
|
long accountId;
|
||||||
|
|
||||||
|
@Column(name = "domain_id")
|
||||||
|
long domainId;
|
||||||
|
|
||||||
|
@Column(name = "object_store_id")
|
||||||
|
long objectStoreId;
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
@Column(name = "name")
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
@Column(name = "state", updatable = true, nullable = false)
|
||||||
|
@Enumerated(value = EnumType.STRING)
|
||||||
|
private State state;
|
||||||
|
|
||||||
|
@Column(name = "size")
|
||||||
|
Long size;
|
||||||
|
|
||||||
|
@Column(name = "quota")
|
||||||
|
Integer quota;
|
||||||
|
|
||||||
|
@Column(name = "versioning")
|
||||||
|
boolean versioning;
|
||||||
|
|
||||||
|
@Column(name = "encryption")
|
||||||
|
boolean encryption;
|
||||||
|
|
||||||
|
@Column(name = "object_lock")
|
||||||
|
boolean objectLock;
|
||||||
|
|
||||||
|
@Column(name = "policy")
|
||||||
|
String policy;
|
||||||
|
|
||||||
|
@Column(name = "bucket_url")
|
||||||
|
String bucketURL;
|
||||||
|
|
||||||
|
@Column(name = "access_key")
|
||||||
|
String accessKey;
|
||||||
|
|
||||||
|
@Column(name = "secret_key")
|
||||||
|
String secretKey;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.CREATED_COLUMN)
|
||||||
|
Date created;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||||
|
Date removed;
|
||||||
|
|
||||||
|
@Column(name = "uuid")
|
||||||
|
String uuid;
|
||||||
|
|
||||||
|
public BucketVO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BucketVO(long accountId, long domainId, long objectStoreId, String name, Integer quota, boolean versioning,
|
||||||
|
boolean encryption, boolean objectLock, String policy)
|
||||||
|
{
|
||||||
|
this.accountId = accountId;
|
||||||
|
this.domainId = domainId;
|
||||||
|
this.objectStoreId = objectStoreId;
|
||||||
|
this.name = name;
|
||||||
|
state = State.Allocated;
|
||||||
|
uuid = UUID.randomUUID().toString();
|
||||||
|
this.quota = quota;
|
||||||
|
this.versioning = versioning;
|
||||||
|
this.encryption = encryption;
|
||||||
|
this.objectLock = objectLock;
|
||||||
|
this.policy = policy;
|
||||||
|
this.size = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getObjectStoreId() {
|
||||||
|
return objectStoreId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(State state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUuid(String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getQuota() {
|
||||||
|
return quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuota(Integer quota) {
|
||||||
|
this.quota = quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVersioning() {
|
||||||
|
return versioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersioning(boolean versioning) {
|
||||||
|
this.versioning = versioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEncryption() {
|
||||||
|
return encryption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncryption(boolean encryption) {
|
||||||
|
this.encryption = encryption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isObjectLock() {
|
||||||
|
return objectLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObjectLock(boolean objectLock) {
|
||||||
|
this.objectLock = objectLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPolicy() {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolicy(String policy) {
|
||||||
|
this.policy = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBucketURL() {
|
||||||
|
return bucketURL;
|
||||||
|
}
|
||||||
|
public void setBucketURL(String bucketURL) {
|
||||||
|
this.bucketURL = bucketURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessKey() {
|
||||||
|
return accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessKey(String accessKey) {
|
||||||
|
this.accessKey = accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecretKey() {
|
||||||
|
return secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecretKey(String secretKey) {
|
||||||
|
this.secretKey = secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(Long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getEntityType() {
|
||||||
|
return Bucket.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("Bucket %s", new ToStringBuilder(this, ToStringStyle.JSON_STYLE).append("uuid", getUuid()).append("name", getName())
|
||||||
|
.append("ObjectStoreId", getObjectStoreId()).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
// 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 com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface BucketDao extends GenericDao<BucketVO, Long> {
|
||||||
|
List<BucketVO> listByObjectStoreId(long objectStoreId);
|
||||||
|
|
||||||
|
List<BucketVO> listByObjectStoreIdAndAccountId(long objectStoreId, long accountId);
|
||||||
|
|
||||||
|
List<BucketVO> searchByIds(Long[] ids);
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
// 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 com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.naming.ConfigurationException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class BucketDaoImpl extends GenericDaoBase<BucketVO, Long> implements BucketDao {
|
||||||
|
public static final Logger s_logger = Logger.getLogger(BucketDaoImpl.class.getName());
|
||||||
|
private SearchBuilder<BucketVO> searchFilteringStoreId;
|
||||||
|
|
||||||
|
private SearchBuilder<BucketVO> bucketSearch;
|
||||||
|
|
||||||
|
private static final String STORE_ID = "store_id";
|
||||||
|
private static final String STATE = "state";
|
||||||
|
private static final String ACCOUNT_ID = "account_id";
|
||||||
|
|
||||||
|
protected BucketDaoImpl() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
|
super.configure(name, params);
|
||||||
|
|
||||||
|
searchFilteringStoreId = createSearchBuilder();
|
||||||
|
searchFilteringStoreId.and(STORE_ID, searchFilteringStoreId.entity().getObjectStoreId(), SearchCriteria.Op.EQ);
|
||||||
|
searchFilteringStoreId.and(ACCOUNT_ID, searchFilteringStoreId.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
searchFilteringStoreId.and(STATE, searchFilteringStoreId.entity().getState(), SearchCriteria.Op.NEQ);
|
||||||
|
searchFilteringStoreId.done();
|
||||||
|
|
||||||
|
bucketSearch = createSearchBuilder();
|
||||||
|
bucketSearch.and("idIN", bucketSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||||
|
bucketSearch.done();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public List<BucketVO> listByObjectStoreId(long objectStoreId) {
|
||||||
|
SearchCriteria<BucketVO> sc = searchFilteringStoreId.create();
|
||||||
|
sc.setParameters(STORE_ID, objectStoreId);
|
||||||
|
sc.setParameters(STATE, BucketVO.State.Destroyed);
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BucketVO> listByObjectStoreIdAndAccountId(long objectStoreId, long accountId) {
|
||||||
|
SearchCriteria<BucketVO> sc = searchFilteringStoreId.create();
|
||||||
|
sc.setParameters(STORE_ID, objectStoreId);
|
||||||
|
sc.setParameters(ACCOUNT_ID, accountId);
|
||||||
|
sc.setParameters(STATE, BucketVO.State.Destroyed);
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BucketVO> searchByIds(Long[] ids) {
|
||||||
|
SearchCriteria<BucketVO> sc = bucketSearch.create();
|
||||||
|
sc.setParameters("idIN", ids);
|
||||||
|
return search(sc, null, null, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
// 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.usage;
|
||||||
|
|
||||||
|
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 = "bucket_statistics")
|
||||||
|
public class BucketStatisticsVO implements InternalIdentity {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(name = "id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "account_id", updatable = false)
|
||||||
|
private long accountId;
|
||||||
|
|
||||||
|
@Column(name = "bucket_id", updatable = false)
|
||||||
|
private long bucketId;
|
||||||
|
|
||||||
|
@Column(name = "size")
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
protected BucketStatisticsVO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BucketStatisticsVO(long accountId, long bucketId) {
|
||||||
|
this.accountId = accountId;
|
||||||
|
this.bucketId = bucketId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBucketId() {
|
||||||
|
return bucketId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
// 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.usage.dao;
|
||||||
|
|
||||||
|
import com.cloud.usage.BucketStatisticsVO;
|
||||||
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface BucketStatisticsDao extends GenericDao<BucketStatisticsVO, Long> {
|
||||||
|
BucketStatisticsVO findBy(long accountId, long bucketId);
|
||||||
|
|
||||||
|
BucketStatisticsVO lock(long accountId, long bucketId);
|
||||||
|
|
||||||
|
List<BucketStatisticsVO> listBy(long accountId);
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
// 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.usage.dao;
|
||||||
|
|
||||||
|
import com.cloud.usage.BucketStatisticsVO;
|
||||||
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class BucketStatisticsDaoImpl extends GenericDaoBase<BucketStatisticsVO, Long> implements BucketStatisticsDao {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(BucketStatisticsDaoImpl.class);
|
||||||
|
private final SearchBuilder<BucketStatisticsVO> AllFieldsSearch;
|
||||||
|
private final SearchBuilder<BucketStatisticsVO> AccountSearch;
|
||||||
|
|
||||||
|
public BucketStatisticsDaoImpl() {
|
||||||
|
AccountSearch = createSearchBuilder();
|
||||||
|
AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
AccountSearch.done();
|
||||||
|
|
||||||
|
AllFieldsSearch = createSearchBuilder();
|
||||||
|
AllFieldsSearch.and("account", AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||||
|
AllFieldsSearch.and("bucket", AllFieldsSearch.entity().getBucketId(), SearchCriteria.Op.EQ);
|
||||||
|
AllFieldsSearch.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BucketStatisticsVO findBy(long accountId, long bucketId) {
|
||||||
|
SearchCriteria<BucketStatisticsVO> sc = AllFieldsSearch.create();
|
||||||
|
sc.setParameters("account", accountId);
|
||||||
|
sc.setParameters("bucket", bucketId);
|
||||||
|
return findOneBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BucketStatisticsVO lock(long accountId, long bucketId) {
|
||||||
|
SearchCriteria<BucketStatisticsVO> sc = AllFieldsSearch.create();
|
||||||
|
sc.setParameters("account", accountId);
|
||||||
|
sc.setParameters("bucket", bucketId);
|
||||||
|
return lockOneRandomRow(sc, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BucketStatisticsVO> listBy(long accountId) {
|
||||||
|
SearchCriteria<BucketStatisticsVO> sc = AccountSearch.create();
|
||||||
|
sc.setParameters("account", accountId);
|
||||||
|
return search(sc, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,6 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.usage.dao;
|
package com.cloud.usage.dao;
|
||||||
|
|
||||||
|
import com.cloud.usage.BucketStatisticsVO;
|
||||||
import com.cloud.usage.UsageVO;
|
import com.cloud.usage.UsageVO;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
import com.cloud.user.UserStatisticsVO;
|
import com.cloud.user.UserStatisticsVO;
|
||||||
@ -45,6 +46,12 @@ public interface UsageDao extends GenericDao<UsageVO, Long> {
|
|||||||
|
|
||||||
Long getLastUserStatsId();
|
Long getLastUserStatsId();
|
||||||
|
|
||||||
|
Long getLastBucketStatsId();
|
||||||
|
|
||||||
|
void saveBucketStats(List<BucketStatisticsVO> userStats);
|
||||||
|
|
||||||
|
void updateBucketStats(List<BucketStatisticsVO> userStats);
|
||||||
|
|
||||||
List<Long> listPublicTemplatesByAccount(long accountId);
|
List<Long> listPublicTemplatesByAccount(long accountId);
|
||||||
|
|
||||||
Long getLastVmDiskStatsId();
|
Long getLastVmDiskStatsId();
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.usage.dao;
|
package com.cloud.usage.dao;
|
||||||
|
|
||||||
|
import com.cloud.usage.BucketStatisticsVO;
|
||||||
import com.cloud.usage.UsageVO;
|
import com.cloud.usage.UsageVO;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
import com.cloud.user.UserStatisticsVO;
|
import com.cloud.user.UserStatisticsVO;
|
||||||
@ -82,6 +83,13 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||||||
+ "WHERE cloud_usage.usage_type = ? AND cloud_usage.account_id = ? AND cloud_usage.start_date >= ? AND cloud_usage.end_date <= ? "
|
+ "WHERE cloud_usage.usage_type = ? AND cloud_usage.account_id = ? AND cloud_usage.start_date >= ? AND cloud_usage.end_date <= ? "
|
||||||
+ "GROUP BY cloud_usage.usage_id ";
|
+ "GROUP BY cloud_usage.usage_id ";
|
||||||
|
|
||||||
|
private static final String GET_LAST_BUCKET_STATS_ID = "SELECT id FROM cloud_usage.bucket_statistics ORDER BY id DESC LIMIT 1";
|
||||||
|
|
||||||
|
private static final String INSERT_BUCKET_STATS = "INSERT INTO cloud_usage.bucket_statistics (id, account_id, bucket_id, size) VALUES (?,?,?,?)";
|
||||||
|
|
||||||
|
private static final String UPDATE_BUCKET_STATS = "UPDATE cloud_usage.bucket_statistics SET size=? WHERE id=?";
|
||||||
|
|
||||||
|
|
||||||
public UsageDaoImpl() {
|
public UsageDaoImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +293,69 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getLastBucketStatsId() {
|
||||||
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
String sql = GET_LAST_BUCKET_STATS_ID;
|
||||||
|
try {
|
||||||
|
pstmt = txn.prepareAutoCloseStatement(sql);
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return Long.valueOf(rs.getLong(1));
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
s_logger.error("error getting last bucket stats id", ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveBucketStats(List<BucketStatisticsVO> bucketStats) {
|
||||||
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
|
try {
|
||||||
|
txn.start();
|
||||||
|
String sql = INSERT_BUCKET_STATS;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||||
|
for (BucketStatisticsVO bucketStat : bucketStats) {
|
||||||
|
pstmt.setLong(1, bucketStat.getId());
|
||||||
|
pstmt.setLong(2, bucketStat.getAccountId());
|
||||||
|
pstmt.setLong(3, bucketStat.getBucketId());
|
||||||
|
pstmt.setLong(4, bucketStat.getSize());
|
||||||
|
pstmt.addBatch();
|
||||||
|
}
|
||||||
|
pstmt.executeBatch();
|
||||||
|
txn.commit();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
txn.rollback();
|
||||||
|
s_logger.error("error saving bucket stats to cloud_usage db", ex);
|
||||||
|
throw new CloudRuntimeException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBucketStats(List<BucketStatisticsVO> bucketStats) {
|
||||||
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
|
try {
|
||||||
|
txn.start();
|
||||||
|
String sql = UPDATE_BUCKET_STATS;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||||
|
for (BucketStatisticsVO bucketStat : bucketStats) {
|
||||||
|
pstmt.setLong(1, bucketStat.getSize());
|
||||||
|
pstmt.setLong(2, bucketStat.getId());
|
||||||
|
pstmt.addBatch();
|
||||||
|
}
|
||||||
|
pstmt.executeBatch();
|
||||||
|
txn.commit();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
txn.rollback();
|
||||||
|
s_logger.error("error updating bucket stats to cloud_usage db", ex);
|
||||||
|
throw new CloudRuntimeException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Long> listPublicTemplatesByAccount(long accountId) {
|
public List<Long> listPublicTemplatesByAccount(long accountId) {
|
||||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.cloud.utils.db.GenericDao;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ObjectStoreDao extends GenericDao<ObjectStoreVO, Long> {
|
||||||
|
ObjectStoreVO findByName(String name);
|
||||||
|
|
||||||
|
List<ObjectStoreVO> findByProvider(String provider);
|
||||||
|
|
||||||
|
ObjectStoreVO findByUrl(String url);
|
||||||
|
|
||||||
|
List<ObjectStoreVO> listObjectStores();
|
||||||
|
|
||||||
|
List<ObjectStoreVO> searchByIds(Long[] osIds);
|
||||||
|
|
||||||
|
ObjectStoreResponse newObjectStoreResponse(ObjectStoreVO store);
|
||||||
|
|
||||||
|
ObjectStoreResponse setObjectStoreResponse(ObjectStoreResponse storeData, ObjectStoreVO store);
|
||||||
|
|
||||||
|
Integer countAllObjectStores();
|
||||||
|
}
|
||||||
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.cloud.utils.db.GenericDaoBase;
|
||||||
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.naming.ConfigurationException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ObjectStoreDaoImpl extends GenericDaoBase<ObjectStoreVO, Long> implements ObjectStoreDao {
|
||||||
|
private SearchBuilder<ObjectStoreVO> nameSearch;
|
||||||
|
private SearchBuilder<ObjectStoreVO> providerSearch;
|
||||||
|
@Inject
|
||||||
|
private ConfigurationDao _configDao;
|
||||||
|
private final SearchBuilder<ObjectStoreVO> osSearch;
|
||||||
|
|
||||||
|
private SearchBuilder<ObjectStoreVO> urlSearch;
|
||||||
|
|
||||||
|
protected ObjectStoreDaoImpl() {
|
||||||
|
osSearch = createSearchBuilder();
|
||||||
|
osSearch.and("idIN", osSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||||
|
osSearch.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
|
super.configure(name, params);
|
||||||
|
|
||||||
|
nameSearch = createSearchBuilder();
|
||||||
|
nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
|
nameSearch.done();
|
||||||
|
|
||||||
|
providerSearch = createSearchBuilder();
|
||||||
|
providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
|
||||||
|
providerSearch.done();
|
||||||
|
|
||||||
|
urlSearch = createSearchBuilder();
|
||||||
|
urlSearch.and("url", urlSearch.entity().getUrl(), SearchCriteria.Op.EQ);
|
||||||
|
urlSearch.done();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectStoreVO findByName(String name) {
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = nameSearch.create();
|
||||||
|
sc.setParameters("name", name);
|
||||||
|
return findOneBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ObjectStoreVO> findByProvider(String provider) {
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = providerSearch.create();
|
||||||
|
sc.setParameters("providerName", provider);
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectStoreVO findByUrl(String url) {
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = urlSearch.create();
|
||||||
|
sc.setParameters("url", url);
|
||||||
|
return findOneBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ObjectStoreVO> listObjectStores() {
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = createSearchCriteria();
|
||||||
|
return listBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ObjectStoreVO> searchByIds(Long[] osIds) {
|
||||||
|
// 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<ObjectStoreVO> osList = new ArrayList<>();
|
||||||
|
// query details by batches
|
||||||
|
int curr_index = 0;
|
||||||
|
if (osIds.length > DETAILS_BATCH_SIZE) {
|
||||||
|
while ((curr_index + DETAILS_BATCH_SIZE) <= osIds.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] = osIds[j];
|
||||||
|
}
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = osSearch.create();
|
||||||
|
sc.setParameters("idIN", ids);
|
||||||
|
List<ObjectStoreVO> stores = searchIncludingRemoved(sc, null, null, false);
|
||||||
|
if (stores != null) {
|
||||||
|
osList.addAll(stores);
|
||||||
|
}
|
||||||
|
curr_index += DETAILS_BATCH_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (curr_index < osIds.length) {
|
||||||
|
int batch_size = (osIds.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] = osIds[j];
|
||||||
|
}
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = osSearch.create();
|
||||||
|
sc.setParameters("idIN", ids);
|
||||||
|
List<ObjectStoreVO> stores = searchIncludingRemoved(sc, null, null, false);
|
||||||
|
if (stores != null) {
|
||||||
|
osList.addAll(stores);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return osList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectStoreResponse newObjectStoreResponse(ObjectStoreVO store) {
|
||||||
|
ObjectStoreResponse osResponse = new ObjectStoreResponse();
|
||||||
|
osResponse.setId(store.getUuid());
|
||||||
|
osResponse.setName(store.getName());
|
||||||
|
osResponse.setProviderName(store.getProviderName());
|
||||||
|
String url = store.getUrl();
|
||||||
|
osResponse.setUrl(url);
|
||||||
|
osResponse.setObjectName("objectstore");
|
||||||
|
return osResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectStoreResponse setObjectStoreResponse(ObjectStoreResponse storeData, ObjectStoreVO store) {
|
||||||
|
return storeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer countAllObjectStores() {
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = createSearchCriteria();
|
||||||
|
return getCount(sc);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
// 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.ResourceDetail;
|
||||||
|
|
||||||
|
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 = "object_store_details")
|
||||||
|
public class ObjectStoreDetailVO implements ResourceDetail {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(name = "id")
|
||||||
|
long id;
|
||||||
|
|
||||||
|
@Column(name = "store_id")
|
||||||
|
long resourceId;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@Column(name = "value")
|
||||||
|
String value;
|
||||||
|
|
||||||
|
public ObjectStoreDetailVO() {
|
||||||
|
}
|
||||||
|
public ObjectStoreDetailVO(long storeId, String name, String value) {
|
||||||
|
this.resourceId = storeId;
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getResourceId() {
|
||||||
|
return resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDisplay() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
// 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 com.cloud.utils.db.GenericDao;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface ObjectStoreDetailsDao extends GenericDao<ObjectStoreDetailVO, Long>, ResourceDetailsDao<ObjectStoreDetailVO> {
|
||||||
|
|
||||||
|
void update(long storeId, Map<String, String> details);
|
||||||
|
|
||||||
|
Map<String, String> getDetails(long storeId);
|
||||||
|
|
||||||
|
void deleteDetails(long storeId);
|
||||||
|
}
|
||||||
@ -0,0 +1,104 @@
|
|||||||
|
// 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 com.cloud.utils.crypt.DBEncryptionUtil;
|
||||||
|
import com.cloud.utils.db.QueryBuilder;
|
||||||
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ObjectStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ObjectStoreDetailVO> implements ObjectStoreDetailsDao {
|
||||||
|
|
||||||
|
protected final SearchBuilder<ObjectStoreDetailVO> storeSearch;
|
||||||
|
|
||||||
|
public ObjectStoreDetailsDaoImpl() {
|
||||||
|
super();
|
||||||
|
storeSearch = createSearchBuilder();
|
||||||
|
storeSearch.and("store", storeSearch.entity().getResourceId(), Op.EQ);
|
||||||
|
storeSearch.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(long storeId, Map<String, String> details) {
|
||||||
|
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||||
|
SearchCriteria<ObjectStoreDetailVO> sc = storeSearch.create();
|
||||||
|
sc.setParameters("store", storeId);
|
||||||
|
|
||||||
|
txn.start();
|
||||||
|
expunge(sc);
|
||||||
|
for (Map.Entry<String, String> entry : details.entrySet()) {
|
||||||
|
ObjectStoreDetailVO detail = new ObjectStoreDetailVO(storeId, entry.getKey(), entry.getValue());
|
||||||
|
persist(detail);
|
||||||
|
}
|
||||||
|
txn.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getDetails(long storeId) {
|
||||||
|
SearchCriteria<ObjectStoreDetailVO> sc = storeSearch.create();
|
||||||
|
sc.setParameters("store", storeId);
|
||||||
|
|
||||||
|
List<ObjectStoreDetailVO> details = listBy(sc);
|
||||||
|
Map<String, String> detailsMap = new HashMap<String, String>();
|
||||||
|
for (ObjectStoreDetailVO detail : details) {
|
||||||
|
String name = detail.getName();
|
||||||
|
String value = detail.getValue();
|
||||||
|
if (name.equals(ApiConstants.KEY)) {
|
||||||
|
value = DBEncryptionUtil.decrypt(value);
|
||||||
|
}
|
||||||
|
detailsMap.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return detailsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteDetails(long storeId) {
|
||||||
|
SearchCriteria<ObjectStoreDetailVO> sc = storeSearch.create();
|
||||||
|
sc.setParameters("store", storeId);
|
||||||
|
|
||||||
|
List<ObjectStoreDetailVO> results = search(sc, null);
|
||||||
|
for (ObjectStoreDetailVO result : results) {
|
||||||
|
remove(result.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectStoreDetailVO findDetail(long storeId, String name) {
|
||||||
|
QueryBuilder<ObjectStoreDetailVO> sc = QueryBuilder.create(ObjectStoreDetailVO.class);
|
||||||
|
sc.and(sc.entity().getResourceId(), Op.EQ, storeId);
|
||||||
|
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||||
|
return sc.find();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||||
|
// ToDo: Add Display
|
||||||
|
super.addDetail(new ObjectStoreDetailVO(resourceId, key, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* 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.storage.object.ObjectStore;
|
||||||
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.TableGenerator;
|
||||||
|
import javax.persistence.Transient;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "object_store")
|
||||||
|
public class ObjectStoreVO implements ObjectStore {
|
||||||
|
@Id
|
||||||
|
@TableGenerator(name = "object_store_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "object_store_seq", allocationSize = 1)
|
||||||
|
@Column(name = "id", nullable = false)
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
@Column(name = "name", nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "uuid", nullable = false)
|
||||||
|
private String uuid;
|
||||||
|
|
||||||
|
@Column(name = "url", nullable = false, length = 2048)
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Column(name = "object_provider_name", nullable = false)
|
||||||
|
private String providerName;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.CREATED_COLUMN)
|
||||||
|
private Date created;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||||
|
private Date removed;
|
||||||
|
|
||||||
|
@Column(name = "total_size")
|
||||||
|
private Long totalSize;
|
||||||
|
|
||||||
|
@Column(name = "used_bytes")
|
||||||
|
private Long usedBytes;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
Map<String, String> details;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProviderName() {
|
||||||
|
return this.providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderName(String provider) {
|
||||||
|
this.providerName = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUuid(String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUuid() {
|
||||||
|
return this.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreated(Date created) {
|
||||||
|
this.created = created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoved(Date removed) {
|
||||||
|
this.removed = removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTotalSize() {
|
||||||
|
return totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalSize(Long totalSize) {
|
||||||
|
this.totalSize = totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUsedBytes() {
|
||||||
|
return usedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsedBytes(Long usedBytes) {
|
||||||
|
this.usedBytes = usedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDetails(Map<String, String> details) {
|
||||||
|
this.details = details;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -283,4 +283,6 @@
|
|||||||
<bean id="vnfTemplateNicDaoImpl" class="com.cloud.storage.dao.VnfTemplateNicDaoImpl" />
|
<bean id="vnfTemplateNicDaoImpl" class="com.cloud.storage.dao.VnfTemplateNicDaoImpl" />
|
||||||
<bean id="ClusterDrsPlanDaoImpl" class="org.apache.cloudstack.cluster.dao.ClusterDrsPlanDaoImpl" />
|
<bean id="ClusterDrsPlanDaoImpl" class="org.apache.cloudstack.cluster.dao.ClusterDrsPlanDaoImpl" />
|
||||||
<bean id="ClusterDrsPlanDetailsDaoImpl" class="org.apache.cloudstack.cluster.dao.ClusterDrsPlanMigrationDaoImpl" />
|
<bean id="ClusterDrsPlanDetailsDaoImpl" class="org.apache.cloudstack.cluster.dao.ClusterDrsPlanMigrationDaoImpl" />
|
||||||
|
<bean id="objectStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ObjectStoreDetailsDaoImpl" />
|
||||||
|
<bean id="bucketStatisticsDaoImpl" class="com.cloud.usage.dao.BucketStatisticsDaoImpl" />
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
@ -233,3 +233,69 @@ ALTER TABLE `cloud`.`storage_pool_tags` MODIFY tag text NOT NULL;
|
|||||||
ALTER TABLE `cloud`.`host_tags` ADD COLUMN is_tag_a_rule int(1) UNSIGNED not null DEFAULT 0;
|
ALTER TABLE `cloud`.`host_tags` ADD COLUMN is_tag_a_rule int(1) UNSIGNED not null DEFAULT 0;
|
||||||
|
|
||||||
ALTER TABLE `cloud`.`host_tags` MODIFY tag text NOT NULL;
|
ALTER TABLE `cloud`.`host_tags` MODIFY tag text NOT NULL;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `cloud`.`object_store`;
|
||||||
|
CREATE TABLE `cloud`.`object_store` (
|
||||||
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||||
|
`name` varchar(255) NOT NULL COMMENT 'name of object store',
|
||||||
|
`object_provider_name` varchar(255) NOT NULL COMMENT 'id of object_store_provider',
|
||||||
|
`url` varchar(255) NOT NULL COMMENT 'url of the object store',
|
||||||
|
`uuid` varchar(255) COMMENT 'uuid of object store',
|
||||||
|
`created` datetime COMMENT 'date the object store first signed on',
|
||||||
|
`removed` datetime COMMENT 'date removed if not null',
|
||||||
|
`total_size` bigint unsigned COMMENT 'storage total size statistics',
|
||||||
|
`used_bytes` bigint unsigned COMMENT 'storage available bytes statistics',
|
||||||
|
PRIMARY KEY(`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `cloud`.`object_store_details`;
|
||||||
|
CREATE TABLE `cloud`.`object_store_details` (
|
||||||
|
`id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||||
|
`store_id` bigint unsigned NOT NULL COMMENT 'store the detail is related to',
|
||||||
|
`name` varchar(255) NOT NULL COMMENT 'name of the detail',
|
||||||
|
`value` varchar(255) NOT NULL COMMENT 'value of the detail',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
CONSTRAINT `fk_object_store_details__store_id` FOREIGN KEY `fk_object_store__store_id`(`store_id`) REFERENCES `object_store`(`id`) ON DELETE CASCADE,
|
||||||
|
INDEX `i_object_store__name__value`(`name`(128), `value`(128))
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `cloud`.`bucket`;
|
||||||
|
CREATE TABLE `cloud`.`bucket` (
|
||||||
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||||
|
`name` varchar(255) NOT NULL COMMENT 'name of bucket',
|
||||||
|
`object_store_id` varchar(255) NOT NULL COMMENT 'id of object_store',
|
||||||
|
`state` varchar(255) NOT NULL COMMENT 'state of the bucket',
|
||||||
|
`uuid` varchar(255) COMMENT 'uuid of bucket',
|
||||||
|
`domain_id` bigint unsigned NOT NULL COMMENT 'domain the bucket belongs to',
|
||||||
|
`account_id` bigint unsigned NOT NULL COMMENT 'owner of this bucket',
|
||||||
|
`size` bigint unsigned COMMENT 'total size of bucket objects',
|
||||||
|
`quota` bigint unsigned COMMENT 'Allocated bucket quota in GB',
|
||||||
|
`versioning` boolean COMMENT 'versioning enable/disable',
|
||||||
|
`encryption` boolean COMMENT 'encryption enable/disbale',
|
||||||
|
`object_lock` boolean COMMENT 'Lock objects in bucket',
|
||||||
|
`policy` varchar(255) COMMENT 'Bucket Access Policy',
|
||||||
|
`access_key` varchar(255) COMMENT 'Bucket Access Key',
|
||||||
|
`secret_key` varchar(255) COMMENT 'Bucket Secret Key',
|
||||||
|
`bucket_url` varchar(255) COMMENT 'URL to access bucket',
|
||||||
|
`created` datetime COMMENT 'date the bucket was created',
|
||||||
|
`removed` datetime COMMENT 'date removed if not null',
|
||||||
|
PRIMARY KEY(`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `cloud`.`bucket_statistics`;
|
||||||
|
CREATE TABLE `cloud`.`bucket_statistics` (
|
||||||
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||||
|
`account_id` bigint unsigned NOT NULL COMMENT 'owner of this bucket',
|
||||||
|
`bucket_id` bigint unsigned NOT NULL COMMENT 'id of this bucket',
|
||||||
|
`size` bigint unsigned COMMENT 'total size of bucket objects',
|
||||||
|
PRIMARY KEY(`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `cloud_usage`.`bucket_statistics`;
|
||||||
|
CREATE TABLE `cloud_usage`.`bucket_statistics` (
|
||||||
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||||
|
`account_id` bigint unsigned NOT NULL COMMENT 'owner of this bucket',
|
||||||
|
`bucket_id` bigint unsigned NOT NULL COMMENT 'id of this bucket',
|
||||||
|
`size` bigint unsigned COMMENT 'total size of bucket objects',
|
||||||
|
PRIMARY KEY(`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|||||||
@ -87,4 +87,8 @@
|
|||||||
<bean id="storageStrategyFactoryImpl" class="org.apache.cloudstack.storage.helper.StorageStrategyFactoryImpl" />
|
<bean id="storageStrategyFactoryImpl" class="org.apache.cloudstack.storage.helper.StorageStrategyFactoryImpl" />
|
||||||
<bean id="vmsnapshotDetailsDao" class="com.cloud.vm.snapshot.dao.VMSnapshotDetailsDaoImpl" />
|
<bean id="vmsnapshotDetailsDao" class="com.cloud.vm.snapshot.dao.VMSnapshotDetailsDaoImpl" />
|
||||||
<bean id="snapshotManager" class="com.cloud.storage.snapshot.SnapshotManagerImpl" />
|
<bean id="snapshotManager" class="com.cloud.storage.snapshot.SnapshotManagerImpl" />
|
||||||
|
<bean id="objectStoreProviderManagerImpl" class="org.apache.cloudstack.storage.object.manager.ObjectStoreProviderManagerImpl" />
|
||||||
|
<bean id="objectStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ObjectStoreDaoImpl" />
|
||||||
|
<bean id="objectStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ObjectStoreDetailsDaoImpl" />
|
||||||
|
<bean id="objectStoreHelper" class="org.apache.cloudstack.storage.object.datastore.ObjectStoreHelper" />
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
37
engine/storage/object/pom.xml
Normal file
37
engine/storage/object/pom.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>cloud-engine-storage-object</artifactId>
|
||||||
|
<name>Apache CloudStack Engine Storage Object Component</name>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine</artifactId>
|
||||||
|
<version>4.19.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,196 @@
|
|||||||
|
// 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.object;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.Answer;
|
||||||
|
import com.cloud.agent.api.to.DataObjectType;
|
||||||
|
import com.cloud.agent.api.to.DataTO;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.BucketInfo;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class BucketObject implements BucketInfo {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDomainId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getAccountId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getEntityType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPayload(Object data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPayload() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bucket getBucket() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUri() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataTO getTO() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStore getDataStore() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getSize() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getQuota() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVersioning() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEncryption() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isObjectLock() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPolicy() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBucketURL() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSecretKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getPhysicalSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataObjectType getType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUuid() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean delete() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEvent(ObjectInDataStoreStateMachine.Event event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void incRefCount() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decRefCount() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getRefCount() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getObjectStoreId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getCreated() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State getState() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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.object;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectStorageService;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
public class ObjectStorageServiceImpl implements ObjectStorageService {
|
||||||
|
|
||||||
|
private static final Logger s_logger = Logger.getLogger(ObjectStorageServiceImpl.class);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.object.manager;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectStoreProvider;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreEntity;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.storage.object.store.ObjectStoreImpl;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ObjectStoreProviderManagerImpl implements ObjectStoreProviderManager, Configurable {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(ObjectStoreProviderManagerImpl.class);
|
||||||
|
@Inject
|
||||||
|
ObjectStoreDao objectStoreDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
DataStoreProviderManager providerManager;
|
||||||
|
|
||||||
|
Map<String, ObjectStoreDriver> driverMaps;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void config() {
|
||||||
|
driverMaps = new HashMap<String, ObjectStoreDriver>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectStoreEntity getObjectStore(long objectStoreId) {
|
||||||
|
ObjectStoreVO objectStore = objectStoreDao.findById(objectStoreId);
|
||||||
|
String providerName = objectStore.getProviderName();
|
||||||
|
ObjectStoreProvider provider = (ObjectStoreProvider)providerManager.getDataStoreProvider(providerName);
|
||||||
|
ObjectStoreEntity objStore = ObjectStoreImpl.getDataStore(objectStore, driverMaps.get(provider.getName()), provider);
|
||||||
|
return objStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean registerDriver(String providerName, ObjectStoreDriver driver) {
|
||||||
|
if (driverMaps.containsKey(providerName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
driverMaps.put(providerName, driver);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectStoreEntity getObjectStore(String uuid) {
|
||||||
|
ObjectStoreVO objectStore = objectStoreDao.findByUuid(uuid);
|
||||||
|
return getObjectStore(objectStore.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DataStore> listObjectStores() {
|
||||||
|
List<ObjectStoreVO> stores = objectStoreDao.listObjectStores();
|
||||||
|
List<DataStore> ObjectStores = new ArrayList<DataStore>();
|
||||||
|
for (ObjectStoreVO store : stores) {
|
||||||
|
ObjectStores.add(getObjectStore(store.getId()));
|
||||||
|
}
|
||||||
|
return ObjectStores;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DataStore> listObjectStoreByProvider(String provider) {
|
||||||
|
List<ObjectStoreVO> stores = objectStoreDao.findByProvider(provider);
|
||||||
|
List<DataStore> ObjectStores = new ArrayList<DataStore>();
|
||||||
|
for (ObjectStoreVO store : stores) {
|
||||||
|
ObjectStores.add(getObjectStore(store.getId()));
|
||||||
|
}
|
||||||
|
return ObjectStores;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConfigComponentName() {
|
||||||
|
return ObjectStoreProviderManager.class.getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
|
return new ConfigKey<?>[] { };
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* 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.object.store;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import com.cloud.storage.DataStoreRole;
|
||||||
|
import com.cloud.utils.component.ComponentContext;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectStoreProvider;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreEntity;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ObjectStoreImpl implements ObjectStoreEntity {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(ObjectStoreImpl.class);
|
||||||
|
|
||||||
|
protected ObjectStoreDriver driver;
|
||||||
|
protected ObjectStoreVO objectStoreVO;
|
||||||
|
protected ObjectStoreProvider provider;
|
||||||
|
|
||||||
|
public ObjectStoreImpl() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void configure(ObjectStoreVO objectStoreVO, ObjectStoreDriver objectStoreDriver, ObjectStoreProvider provider) {
|
||||||
|
this.driver = objectStoreDriver;
|
||||||
|
this.objectStoreVO = objectStoreVO;
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ObjectStoreEntity getDataStore(ObjectStoreVO objectStoreVO, ObjectStoreDriver objectStoreDriver, ObjectStoreProvider provider) {
|
||||||
|
ObjectStoreImpl instance = ComponentContext.inject(ObjectStoreImpl.class);
|
||||||
|
instance.configure(objectStoreVO, objectStoreDriver, provider);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreDriver getDriver() {
|
||||||
|
return this.driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreRole getRole() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return this.objectStoreVO.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUri() {
|
||||||
|
return this.objectStoreVO.getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scope getScope() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUuid() {
|
||||||
|
return this.objectStoreVO.getUuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreated() {
|
||||||
|
return this.objectStoreVO.getCreated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return objectStoreVO.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataObject create(DataObject obj) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bucket createBucket(Bucket bucket, boolean objectLock) {
|
||||||
|
return driver.createBucket(bucket, objectLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucket(String bucketName) {
|
||||||
|
return driver.deleteBucket(bucketName, objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBucketEncryption(String bucketName) {
|
||||||
|
return driver.setBucketEncryption(bucketName, objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucketEncryption(String bucketName) {
|
||||||
|
return driver.deleteBucketEncryption(bucketName, objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBucketVersioning(String bucketName) {
|
||||||
|
return driver.setBucketVersioning(bucketName, objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucketVersioning(String bucketName) {
|
||||||
|
return driver.deleteBucketVersioning(bucketName, objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBucketPolicy(String bucketName, String policy) {
|
||||||
|
driver.setBucketPolicy(bucketName, policy, objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setQuota(String bucketName, int quota) {
|
||||||
|
driver.setBucketQuota(bucketName, objectStoreVO.getId(), quota);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Long> getAllBucketsUsage() {
|
||||||
|
return driver.getAllBucketsUsage(objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Bucket> listBuckets() {
|
||||||
|
return driver.listBuckets(objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create user if not exists
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean createUser(long accountId) {
|
||||||
|
return driver.createUser(accountId, objectStoreVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean delete(DataObject obj) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreTO getTO() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProviderName() {
|
||||||
|
return objectStoreVO.getProviderName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUrl() {
|
||||||
|
return objectStoreVO.getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.object.store.lifecycle;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
|
||||||
|
|
||||||
|
public interface ObjectStoreLifeCycle extends DataStoreLifeCycle {
|
||||||
|
}
|
||||||
@ -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.
|
||||||
|
-->
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||||
|
http://www.springframework.org/schema/context
|
||||||
|
http://www.springframework.org/schema/context/spring-context.xsd"
|
||||||
|
>
|
||||||
|
<bean id="objectStoreDao" class="org.apache.cloudstack.storage.datastore.db.ObjectStoreDaoImpl" />
|
||||||
|
<bean id="objectStoreProviderMgr"
|
||||||
|
class="org.apache.cloudstack.storage.object.manager.ObjectStoreProviderManagerImpl" />
|
||||||
|
<bean id="objectStoreHelper"
|
||||||
|
class="org.apache.cloudstack.storage.object.datastore.ObjectStoreHelper" />
|
||||||
|
<bean id="bucketDao" class="com.cloud.storage.dao.BucketDaoImpl" />
|
||||||
|
|
||||||
|
</beans>
|
||||||
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* 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.object.manager;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectStoreProvider;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreEntity;
|
||||||
|
import org.apache.cloudstack.storage.object.store.ObjectStoreImpl;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mockStatic;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ObjectStoreProviderManagerImplTest extends TestCase{
|
||||||
|
|
||||||
|
ObjectStoreProviderManagerImpl objectStoreProviderManagerImplSpy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStoreDao objectStoreDao;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStoreVO objectStoreVO;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
DataStoreProviderManager providerManager;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStoreProvider provider;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
Map<String, ObjectStoreDriver> driverMaps;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStoreDriver objectStoreDriver;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStoreEntity objectStoreEntity;
|
||||||
|
|
||||||
|
MockedStatic<ObjectStoreImpl> mockObjectStoreImpl;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup(){
|
||||||
|
objectStoreProviderManagerImplSpy = Mockito.spy(new ObjectStoreProviderManagerImpl());
|
||||||
|
objectStoreProviderManagerImplSpy.objectStoreDao = objectStoreDao;
|
||||||
|
objectStoreProviderManagerImplSpy.providerManager = providerManager;
|
||||||
|
objectStoreProviderManagerImplSpy.driverMaps = driverMaps;
|
||||||
|
mockObjectStoreImpl = mockStatic(ObjectStoreImpl.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getObjectStoreTest() {
|
||||||
|
Mockito.doReturn(objectStoreVO).when(objectStoreDao).findById(Mockito.anyLong());
|
||||||
|
Mockito.doReturn(provider).when(providerManager).getDataStoreProvider(Mockito.anyString());
|
||||||
|
Mockito.doReturn(objectStoreDriver).when(driverMaps).get(Mockito.anyString());
|
||||||
|
Mockito.doReturn("Simulator").when(provider).getName();
|
||||||
|
Mockito.doReturn("Simulator").when(objectStoreVO).getProviderName();
|
||||||
|
|
||||||
|
when(ObjectStoreImpl.getDataStore(Mockito.any(ObjectStoreVO.class), Mockito.any(ObjectStoreDriver.class),
|
||||||
|
Mockito.any(ObjectStoreProvider.class))).thenReturn(objectStoreEntity);
|
||||||
|
assertNotNull(objectStoreProviderManagerImplSpy.getObjectStore(1L));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listObjectStoresTest() {
|
||||||
|
List<ObjectStoreVO> stores = new ArrayList<>();
|
||||||
|
stores.add(objectStoreVO);
|
||||||
|
Mockito.doReturn(objectStoreVO).when(objectStoreDao).findById(Mockito.anyLong());
|
||||||
|
Mockito.doReturn(provider).when(providerManager).getDataStoreProvider(Mockito.anyString());
|
||||||
|
Mockito.doReturn(objectStoreDriver).when(driverMaps).get(Mockito.anyString());
|
||||||
|
Mockito.doReturn("Simulator").when(provider).getName();
|
||||||
|
Mockito.doReturn("Simulator").when(objectStoreVO).getProviderName();
|
||||||
|
when(ObjectStoreImpl.getDataStore(Mockito.any(ObjectStoreVO.class), Mockito.any(ObjectStoreDriver.class),
|
||||||
|
Mockito.any(ObjectStoreProvider.class))).thenReturn(objectStoreEntity);
|
||||||
|
Mockito.doReturn(stores).when(objectStoreDao).listObjectStores();
|
||||||
|
assertEquals(1, objectStoreProviderManagerImplSpy.listObjectStores().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
mockObjectStoreImpl.close();
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
79
engine/storage/object/src/test/resource/testContext.xml
Normal file
79
engine/storage/object/src/test/resource/testContext.xml
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/tx
|
||||||
|
http://www.springframework.org/schema/tx/spring-tx.xsd
|
||||||
|
http://www.springframework.org/schema/aop
|
||||||
|
http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||||
|
http://www.springframework.org/schema/context
|
||||||
|
http://www.springframework.org/schema/context/spring-context.xsd">
|
||||||
|
<context:annotation-config />
|
||||||
|
<context:component-scan base-package="org.apache.cloudstack.storage" />
|
||||||
|
<context:component-scan
|
||||||
|
base-package="org.apache.cloudstack.engine.subsystem.api.storage" />
|
||||||
|
<context:component-scan base-package="com.cloud.utils.db" />
|
||||||
|
<context:component-scan base-package="com.cloud.utils.component" />
|
||||||
|
<context:component-scan base-package="com.cloud.host.dao" />
|
||||||
|
<context:component-scan base-package="com.cloud.dc.dao" />
|
||||||
|
<context:component-scan base-package="com.cloud.dc.dao" />
|
||||||
|
<context:component-scan base-package="org.apache.cloudstack.framework" />
|
||||||
|
|
||||||
|
<tx:annotation-driven transaction-manager="transactionManager" />
|
||||||
|
<bean class="org.apache.cloudstack.storage.volume.test.TestConfiguration" />
|
||||||
|
<aop:config proxy-target-class="true">
|
||||||
|
<aop:aspect id="dbContextBuilder" ref="transactionContextBuilder">
|
||||||
|
<aop:pointcut id="captureAnyMethod" expression="@annotation(com.cloud.utils.db.DB)" />
|
||||||
|
<aop:around pointcut-ref="captureAnyMethod" method="AroundAnyMethod" />
|
||||||
|
</aop:aspect>
|
||||||
|
</aop:config>
|
||||||
|
|
||||||
|
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
|
||||||
|
|
||||||
|
<bean id="onwireRegistry" class="org.apache.cloudstack.framework.serializer.OnwireClassRegistry"
|
||||||
|
init-method="scan" >
|
||||||
|
<property name="packages">
|
||||||
|
<list>
|
||||||
|
<value>org.apache.cloudstack.framework</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="messageSerializer" class="org.apache.cloudstack.framework.serializer.JsonMessageSerializer">
|
||||||
|
<property name="onwireClassRegistry" ref="onwireRegistry" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="transportProvider" class="org.apache.cloudstack.framework.server.ServerTransportProvider" init-method="initialize">
|
||||||
|
<property name="workerPoolSize" value="5" />
|
||||||
|
<property name="nodeId" value="Node1" />
|
||||||
|
<property name="messageSerializer" ref="messageSerializer" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="rpcProvider" class="org.apache.cloudstack.framework.rpc.RpcProviderImpl" init-method="initialize">
|
||||||
|
<constructor-arg ref="transportProvider" />
|
||||||
|
<property name="messageSerializer" ref="messageSerializer" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="eventBus" class = "org.apache.cloudstack.framework.eventbus.EventBusBase" />
|
||||||
|
|
||||||
|
</beans>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
mock-maker-inline
|
||||||
@ -26,6 +26,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
||||||
@ -40,6 +41,8 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
|||||||
PrimaryDataStoreProviderManager primaryStoreMgr;
|
PrimaryDataStoreProviderManager primaryStoreMgr;
|
||||||
@Inject
|
@Inject
|
||||||
ImageStoreProviderManager imageDataStoreMgr;
|
ImageStoreProviderManager imageDataStoreMgr;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreProviderManager objectStoreProviderMgr;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataStore getDataStore(long storeId, DataStoreRole role) {
|
public DataStore getDataStore(long storeId, DataStoreRole role) {
|
||||||
@ -50,6 +53,8 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
|||||||
return imageDataStoreMgr.getImageStore(storeId);
|
return imageDataStoreMgr.getImageStore(storeId);
|
||||||
} else if (role == DataStoreRole.ImageCache) {
|
} else if (role == DataStoreRole.ImageCache) {
|
||||||
return imageDataStoreMgr.getImageStore(storeId);
|
return imageDataStoreMgr.getImageStore(storeId);
|
||||||
|
} else if (role == DataStoreRole.Object) {
|
||||||
|
return objectStoreProviderMgr.getObjectStore(storeId);
|
||||||
}
|
}
|
||||||
} catch (CloudRuntimeException e) {
|
} catch (CloudRuntimeException e) {
|
||||||
throw e;
|
throw e;
|
||||||
@ -63,6 +68,8 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
|||||||
return primaryStoreMgr.getPrimaryDataStore(uuid);
|
return primaryStoreMgr.getPrimaryDataStore(uuid);
|
||||||
} else if (role == DataStoreRole.Image) {
|
} else if (role == DataStoreRole.Image) {
|
||||||
return imageDataStoreMgr.getImageStore(uuid);
|
return imageDataStoreMgr.getImageStore(uuid);
|
||||||
|
} else if (role == DataStoreRole.Object) {
|
||||||
|
return objectStoreProviderMgr.getObjectStore(uuid);
|
||||||
}
|
}
|
||||||
throw new CloudRuntimeException("un recognized type" + role);
|
throw new CloudRuntimeException("un recognized type" + role);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -56,6 +58,8 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
|||||||
PrimaryDataStoreProviderManager primaryDataStoreProviderMgr;
|
PrimaryDataStoreProviderManager primaryDataStoreProviderMgr;
|
||||||
@Inject
|
@Inject
|
||||||
ImageStoreProviderManager imageStoreProviderMgr;
|
ImageStoreProviderManager imageStoreProviderMgr;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreProviderManager objectStoreProviderMgr;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataStoreProvider getDataStoreProvider(String name) {
|
public DataStoreProvider getDataStoreProvider(String name) {
|
||||||
@ -144,6 +148,8 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
|||||||
primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener());
|
primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener());
|
||||||
} else if (types.contains(DataStoreProviderType.IMAGE)) {
|
} else if (types.contains(DataStoreProviderType.IMAGE)) {
|
||||||
imageStoreProviderMgr.registerDriver(provider.getName(), (ImageStoreDriver)provider.getDataStoreDriver());
|
imageStoreProviderMgr.registerDriver(provider.getName(), (ImageStoreDriver)provider.getDataStoreDriver());
|
||||||
|
} else if (types.contains(DataStoreProviderType.OBJECT)) {
|
||||||
|
objectStoreProviderMgr.registerDriver(provider.getName(), (ObjectStoreDriver)provider.getDataStoreDriver());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.debug("configure provider failed", e);
|
s_logger.debug("configure provider failed", e);
|
||||||
@ -169,6 +175,11 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
|||||||
return this.getDataStoreProvider(DataStoreProvider.NFS_IMAGE);
|
return this.getDataStoreProvider(DataStoreProvider.NFS_IMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreProvider getDefaultObjectStoreProvider() {
|
||||||
|
return this.getDataStoreProvider(DataStoreProvider.S3_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<StorageProviderResponse> getDataStoreProviders(String type) {
|
public List<StorageProviderResponse> getDataStoreProviders(String type) {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
@ -180,7 +191,9 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
|||||||
return this.getImageDataStoreProviders();
|
return this.getImageDataStoreProviders();
|
||||||
} else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.ImageCache.toString())) {
|
} else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.ImageCache.toString())) {
|
||||||
return this.getCacheDataStoreProviders();
|
return this.getCacheDataStoreProviders();
|
||||||
} else {
|
} else if (type.equalsIgnoreCase(DataStoreProviderType.OBJECT.toString())) {
|
||||||
|
return this.getObjectStoreProviders();
|
||||||
|
}else {
|
||||||
throw new InvalidParameterValueException("Invalid parameter: " + type);
|
throw new InvalidParameterValueException("Invalid parameter: " + type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,4 +236,16 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
|||||||
return providers;
|
return providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<StorageProviderResponse> getObjectStoreProviders() {
|
||||||
|
List<StorageProviderResponse> providers = new ArrayList<StorageProviderResponse>();
|
||||||
|
for (DataStoreProvider provider : providerMap.values()) {
|
||||||
|
if (provider.getTypes().contains(DataStoreProviderType.OBJECT)) {
|
||||||
|
StorageProviderResponse response = new StorageProviderResponse();
|
||||||
|
response.setName(provider.getName());
|
||||||
|
response.setType(DataStoreProviderType.OBJECT.toString());
|
||||||
|
providers.add(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.object;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.to.DataTO;
|
||||||
|
import com.cloud.host.Host;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||||
|
import org.apache.cloudstack.framework.async.AsyncRpcContext;
|
||||||
|
import org.apache.cloudstack.storage.command.CommandResult;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class BaseObjectStoreDriverImpl implements ObjectStoreDriver {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(BaseObjectStoreDriverImpl.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getCapabilities() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataTO getTO(DataObject data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class CreateContext<T> extends AsyncRpcContext<T> {
|
||||||
|
final DataObject data;
|
||||||
|
|
||||||
|
public CreateContext(AsyncCompletionCallback<T> callback, DataObject data) {
|
||||||
|
super(callback);
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
|
||||||
|
copyAsync(srcData, destData, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCopy(DataObject srcData, DataObject destData) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
* 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.object;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.model.AccessControlList;
|
||||||
|
import com.amazonaws.services.s3.model.BucketPolicy;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface ObjectStoreDriver extends DataStoreDriver {
|
||||||
|
Bucket createBucket(Bucket bucket, boolean objectLock);
|
||||||
|
|
||||||
|
List<Bucket> listBuckets(long storeId);
|
||||||
|
|
||||||
|
boolean deleteBucket(String bucketName, long storeId);
|
||||||
|
|
||||||
|
AccessControlList getBucketAcl(String bucketName, long storeId);
|
||||||
|
|
||||||
|
void setBucketAcl(String bucketName, AccessControlList acl, long storeId);
|
||||||
|
|
||||||
|
void setBucketPolicy(String bucketName, String policyType, long storeId);
|
||||||
|
|
||||||
|
BucketPolicy getBucketPolicy(String bucketName, long storeId);
|
||||||
|
|
||||||
|
void deleteBucketPolicy(String bucketName, long storeId);
|
||||||
|
|
||||||
|
boolean createUser(long accountId, long storeId);
|
||||||
|
|
||||||
|
boolean setBucketEncryption(String bucketName, long storeId);
|
||||||
|
|
||||||
|
boolean deleteBucketEncryption(String bucketName, long storeId);
|
||||||
|
|
||||||
|
|
||||||
|
boolean setBucketVersioning(String bucketName, long storeId);
|
||||||
|
|
||||||
|
boolean deleteBucketVersioning(String bucketName, long storeId);
|
||||||
|
|
||||||
|
void setBucketQuota(String bucketName, long storeId, long size);
|
||||||
|
|
||||||
|
Map<String, Long> getAllBucketsUsage(long storeId);
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
* 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.object.datastore;
|
||||||
|
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDetailVO;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ObjectStoreHelper {
|
||||||
|
@Inject
|
||||||
|
ObjectStoreDao ObjectStoreDao;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreDetailsDao ObjectStoreDetailsDao;
|
||||||
|
|
||||||
|
public ObjectStoreVO createObjectStore(Map<String, Object> params, Map<String, String> details) {
|
||||||
|
ObjectStoreVO store = new ObjectStoreVO();
|
||||||
|
|
||||||
|
store.setProviderName((String)params.get("providerName"));
|
||||||
|
store.setUuid(UUID.randomUUID().toString());
|
||||||
|
store.setUrl((String)params.get("url"));
|
||||||
|
store.setName((String)params.get("name"));
|
||||||
|
|
||||||
|
store = ObjectStoreDao.persist(store);
|
||||||
|
|
||||||
|
// persist details
|
||||||
|
if (details != null) {
|
||||||
|
Iterator<String> keyIter = details.keySet().iterator();
|
||||||
|
while (keyIter.hasNext()) {
|
||||||
|
String key = keyIter.next().toString();
|
||||||
|
String value = details.get(key);
|
||||||
|
ObjectStoreDetailVO detail = new ObjectStoreDetailVO(store.getId(), key, value);
|
||||||
|
ObjectStoreDetailsDao.persist(detail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean deleteObjectStore(long id) {
|
||||||
|
ObjectStoreVO store = ObjectStoreDao.findById(id);
|
||||||
|
if (store == null) {
|
||||||
|
throw new CloudRuntimeException("can't find Object store:" + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectStoreDao.remove(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.object.datastore;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ObjectStoreProviderManager {
|
||||||
|
ObjectStoreEntity getObjectStore(String uuid);
|
||||||
|
|
||||||
|
List<DataStore> listObjectStores();
|
||||||
|
|
||||||
|
List<DataStore> listObjectStoreByProvider(String provider);
|
||||||
|
|
||||||
|
ObjectStoreEntity getObjectStore(long objectStoreId);
|
||||||
|
|
||||||
|
boolean registerDriver(String uuid, ObjectStoreDriver driver);
|
||||||
|
|
||||||
|
}
|
||||||
@ -55,6 +55,7 @@ public class QuotaTypes extends UsageTypes {
|
|||||||
quotaTypeList.put(VOLUME_SECONDARY, new QuotaTypes(VOLUME_SECONDARY, "VOLUME_SECONDARY", UsageUnitTypes.GB_MONTH.toString(), "Volume secondary storage usage"));
|
quotaTypeList.put(VOLUME_SECONDARY, new QuotaTypes(VOLUME_SECONDARY, "VOLUME_SECONDARY", UsageUnitTypes.GB_MONTH.toString(), "Volume secondary storage usage"));
|
||||||
quotaTypeList.put(VM_SNAPSHOT_ON_PRIMARY, new QuotaTypes(VM_SNAPSHOT_ON_PRIMARY, "VM_SNAPSHOT_ON_PRIMARY", UsageUnitTypes.GB_MONTH.toString(), "VM Snapshot primary storage usage"));
|
quotaTypeList.put(VM_SNAPSHOT_ON_PRIMARY, new QuotaTypes(VM_SNAPSHOT_ON_PRIMARY, "VM_SNAPSHOT_ON_PRIMARY", UsageUnitTypes.GB_MONTH.toString(), "VM Snapshot primary storage usage"));
|
||||||
quotaTypeList.put(BACKUP, new QuotaTypes(BACKUP, "BACKUP", UsageUnitTypes.GB_MONTH.toString(), "Backup storage usage"));
|
quotaTypeList.put(BACKUP, new QuotaTypes(BACKUP, "BACKUP", UsageUnitTypes.GB_MONTH.toString(), "Backup storage usage"));
|
||||||
|
quotaTypeList.put(BUCKET, new QuotaTypes(BUCKET, "BUCKET", UsageUnitTypes.GB_MONTH.toString(), "Object Store bucket usage"));
|
||||||
quotaTypeMap = Collections.unmodifiableMap(quotaTypeList);
|
quotaTypeMap = Collections.unmodifiableMap(quotaTypeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,7 @@ import org.apache.cloudstack.response.VolumeMetricsResponse;
|
|||||||
import org.apache.cloudstack.response.VolumeMetricsStatsResponse;
|
import org.apache.cloudstack.response.VolumeMetricsStatsResponse;
|
||||||
import org.apache.cloudstack.response.ZoneMetricsResponse;
|
import org.apache.cloudstack.response.ZoneMetricsResponse;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
|
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
|
||||||
import org.apache.commons.beanutils.BeanUtils;
|
import org.apache.commons.beanutils.BeanUtils;
|
||||||
@ -176,6 +177,9 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
|||||||
@Inject
|
@Inject
|
||||||
private VolumeStatsDao volumeStatsDao;
|
private VolumeStatsDao volumeStatsDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ObjectStoreDao objectStoreDao;
|
||||||
|
|
||||||
private static Gson gson = new Gson();
|
private static Gson gson = new Gson();
|
||||||
|
|
||||||
protected MetricsServiceImpl() {
|
protected MetricsServiceImpl() {
|
||||||
@ -557,6 +561,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
|||||||
response.setHosts(hostDao.countAllByType(Host.Type.Routing));
|
response.setHosts(hostDao.countAllByType(Host.Type.Routing));
|
||||||
response.setStoragePools(storagePoolDao.countAll());
|
response.setStoragePools(storagePoolDao.countAll());
|
||||||
response.setImageStores(imageStoreDao.countAllImageStores());
|
response.setImageStores(imageStoreDao.countAllImageStores());
|
||||||
|
response.setObjectStores(objectStoreDao.countAllObjectStores());
|
||||||
response.setSystemvms(vmInstanceDao.listByTypes(VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm).size());
|
response.setSystemvms(vmInstanceDao.listByTypes(VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm).size());
|
||||||
response.setRouters(domainRouterDao.countAllByRole(VirtualRouter.Role.VIRTUAL_ROUTER));
|
response.setRouters(domainRouterDao.countAllByRole(VirtualRouter.Role.VIRTUAL_ROUTER));
|
||||||
response.setInternalLbs(domainRouterDao.countAllByRole(VirtualRouter.Role.INTERNAL_LB_VM));
|
response.setInternalLbs(domainRouterDao.countAllByRole(VirtualRouter.Role.INTERNAL_LB_VM));
|
||||||
|
|||||||
@ -47,6 +47,10 @@ public class InfrastructureResponse extends BaseResponse {
|
|||||||
@Param(description = "Number of images stores")
|
@Param(description = "Number of images stores")
|
||||||
private Integer imageStores;
|
private Integer imageStores;
|
||||||
|
|
||||||
|
@SerializedName("objectstores")
|
||||||
|
@Param(description = "Number of object stores")
|
||||||
|
private Integer objectStores;
|
||||||
|
|
||||||
@SerializedName("systemvms")
|
@SerializedName("systemvms")
|
||||||
@Param(description = "Number of systemvms")
|
@Param(description = "Number of systemvms")
|
||||||
private Integer systemvms;
|
private Integer systemvms;
|
||||||
@ -118,4 +122,8 @@ public class InfrastructureResponse extends BaseResponse {
|
|||||||
public void setAlerts(Integer alerts) { this.alerts = alerts; }
|
public void setAlerts(Integer alerts) { this.alerts = alerts; }
|
||||||
|
|
||||||
public void setInternalLbs(Integer internalLbs) { this.internalLbs = internalLbs; }
|
public void setInternalLbs(Integer internalLbs) { this.internalLbs = internalLbs; }
|
||||||
|
|
||||||
|
public void setObjectStores(Integer objectStores) {
|
||||||
|
this.objectStores = objectStores;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,6 +133,8 @@
|
|||||||
<module>storage/volume/scaleio</module>
|
<module>storage/volume/scaleio</module>
|
||||||
<module>storage/volume/linstor</module>
|
<module>storage/volume/linstor</module>
|
||||||
<module>storage/volume/storpool</module>
|
<module>storage/volume/storpool</module>
|
||||||
|
<module>storage/object/minio</module>
|
||||||
|
<module>storage/object/simulator</module>
|
||||||
|
|
||||||
|
|
||||||
<module>storage-allocators/random</module>
|
<module>storage-allocators/random</module>
|
||||||
@ -187,6 +189,30 @@
|
|||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage</artifactId>
|
||||||
|
<version>4.19.0.0-SNAPSHOT</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId>
|
||||||
|
<version>8.5.2</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio-admin</artifactId>
|
||||||
|
<version>8.5.2</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage-object</artifactId>
|
||||||
|
<version>4.19.0.0-SNAPSHOT</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
|
|||||||
@ -18,12 +18,15 @@
|
|||||||
package org.apache.cloudstack.shutdown;
|
package org.apache.cloudstack.shutdown;
|
||||||
|
|
||||||
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
|
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
@ -39,6 +42,12 @@ public class ShutdownManagerImplTest {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
AsyncJobManager jobManagerMock;
|
AsyncJobManager jobManagerMock;
|
||||||
|
private AutoCloseable closeable;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
closeable = MockitoAnnotations.openMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
private long prepareCountPendingJobs() {
|
private long prepareCountPendingJobs() {
|
||||||
long expectedCount = 1L;
|
long expectedCount = 1L;
|
||||||
@ -75,4 +84,9 @@ public class ShutdownManagerImplTest {
|
|||||||
spy.cancelShutdown();
|
spy.cancelShutdown();
|
||||||
Mockito.verify(jobManagerMock).enableAsyncJobs();
|
Mockito.verify(jobManagerMock).enableAsyncJobs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
closeable.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
57
plugins/storage/object/minio/pom.xml
Normal file
57
plugins/storage/object/minio/pom.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>cloud-plugin-storage-object-minio</artifactId>
|
||||||
|
<name>Apache CloudStack Plugin - MinIO object storage provider</name>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloudstack-plugins</artifactId>
|
||||||
|
<version>4.19.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage-object</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-schema</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId>
|
||||||
|
<version>8.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio-admin</artifactId>
|
||||||
|
<version>8.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,404 @@
|
|||||||
|
/*
|
||||||
|
* 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.driver;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.model.AccessControlList;
|
||||||
|
import com.amazonaws.services.s3.model.BucketPolicy;
|
||||||
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.AccountDetailsDao;
|
||||||
|
import com.cloud.user.dao.AccountDao;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import io.minio.BucketExistsArgs;
|
||||||
|
import io.minio.DeleteBucketEncryptionArgs;
|
||||||
|
import io.minio.MakeBucketArgs;
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import io.minio.RemoveBucketArgs;
|
||||||
|
import io.minio.SetBucketEncryptionArgs;
|
||||||
|
import io.minio.SetBucketPolicyArgs;
|
||||||
|
import io.minio.SetBucketVersioningArgs;
|
||||||
|
import io.minio.admin.MinioAdminClient;
|
||||||
|
import io.minio.admin.QuotaUnit;
|
||||||
|
import io.minio.admin.UserInfo;
|
||||||
|
import io.minio.admin.messages.DataUsageInfo;
|
||||||
|
import io.minio.messages.SseConfiguration;
|
||||||
|
import io.minio.messages.VersioningConfiguration;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.BaseObjectStoreDriverImpl;
|
||||||
|
import org.apache.cloudstack.storage.object.BucketObject;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.crypto.KeyGenerator;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MinIOObjectStoreDriverImpl extends BaseObjectStoreDriverImpl {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(MinIOObjectStoreDriverImpl.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AccountDao _accountDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AccountDetailsDao _accountDetailsDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ObjectStoreDao _storeDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
BucketDao _bucketDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ObjectStoreDetailsDao _storeDetailsDao;
|
||||||
|
|
||||||
|
private static final String ACCESS_KEY = "accesskey";
|
||||||
|
private static final String SECRET_KEY = "secretkey";
|
||||||
|
|
||||||
|
private static final String MINIO_ACCESS_KEY = "minio-accesskey";
|
||||||
|
private static final String MINIO_SECRET_KEY = "minio-secretkey";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreTO getStoreTO(DataStore store) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bucket createBucket(Bucket bucket, boolean objectLock) {
|
||||||
|
//ToDo Client pool mgmt
|
||||||
|
String bucketName = bucket.getName();
|
||||||
|
long storeId = bucket.getObjectStoreId();
|
||||||
|
long accountId = bucket.getAccountId();
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
Account account = _accountDao.findById(accountId);
|
||||||
|
|
||||||
|
if ((_accountDetailsDao.findDetail(accountId, MINIO_ACCESS_KEY) == null)
|
||||||
|
|| (_accountDetailsDao.findDetail(accountId, MINIO_SECRET_KEY) == null)) {
|
||||||
|
throw new CloudRuntimeException("Bucket access credentials unavailable for account: "+account.getAccountName());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
|
||||||
|
throw new CloudRuntimeException("Bucket already exists with name "+ bucketName);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).objectLock(objectLock).build());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BucketVO> buckets = _bucketDao.listByObjectStoreIdAndAccountId(storeId, accountId);
|
||||||
|
StringBuilder resources_builder = new StringBuilder();
|
||||||
|
for(BucketVO exitingBucket : buckets) {
|
||||||
|
resources_builder.append("\"arn:aws:s3:::"+exitingBucket.getName()+"/*\",\n");
|
||||||
|
}
|
||||||
|
resources_builder.append("\"arn:aws:s3:::"+bucketName+"/*\"\n");
|
||||||
|
|
||||||
|
String policy = " {\n" +
|
||||||
|
" \"Statement\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"Action\": \"s3:*\",\n" +
|
||||||
|
" \"Effect\": \"Allow\",\n" +
|
||||||
|
" \"Principal\": \"*\",\n" +
|
||||||
|
" \"Resource\": ["+resources_builder+"]" +
|
||||||
|
" }\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"Version\": \"2012-10-17\"\n" +
|
||||||
|
" }";
|
||||||
|
MinioAdminClient minioAdminClient = getMinIOAdminClient(storeId);
|
||||||
|
String policyName = "acs-"+account.getAccountName()+"-policy";
|
||||||
|
String userName = "acs-"+account.getAccountName();
|
||||||
|
try {
|
||||||
|
minioAdminClient.addCannedPolicy(policyName, policy);
|
||||||
|
minioAdminClient.setPolicy(userName, false, policyName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
String accessKey = _accountDetailsDao.findDetail(accountId, MINIO_ACCESS_KEY).getValue();
|
||||||
|
String secretKey = _accountDetailsDao.findDetail(accountId, MINIO_SECRET_KEY).getValue();
|
||||||
|
ObjectStoreVO store = _storeDao.findById(storeId);
|
||||||
|
BucketVO bucketVO = _bucketDao.findById(bucket.getId());
|
||||||
|
bucketVO.setAccessKey(accessKey);
|
||||||
|
bucketVO.setSecretKey(secretKey);
|
||||||
|
bucketVO.setBucketURL(store.getUrl()+"/"+bucketName);
|
||||||
|
_bucketDao.update(bucket.getId(), bucketVO);
|
||||||
|
return bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Bucket> listBuckets(long storeId) {
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
List<Bucket> bucketsList = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
List<io.minio.messages.Bucket> minIOBuckets = minioClient.listBuckets();
|
||||||
|
for(io.minio.messages.Bucket minIObucket : minIOBuckets) {
|
||||||
|
Bucket bucket = new BucketObject();
|
||||||
|
bucket.setName(minIObucket.name());
|
||||||
|
bucketsList.add(bucket);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
return bucketsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucket(String bucketName, long storeId) {
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
try {
|
||||||
|
if(!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
|
||||||
|
throw new CloudRuntimeException("Bucket doesn't exist: "+ bucketName);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
//ToDo: check bucket empty
|
||||||
|
try {
|
||||||
|
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessControlList getBucketAcl(String bucketName, long storeId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBucketAcl(String bucketName, AccessControlList acl, long storeId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBucketPolicy(String bucketName, String policy, long storeId) {
|
||||||
|
String privatePolicy = "{\"Version\":\"2012-10-17\",\"Statement\":[]}";
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("{\n");
|
||||||
|
builder.append(" \"Statement\": [\n");
|
||||||
|
builder.append(" {\n");
|
||||||
|
builder.append(" \"Action\": [\n");
|
||||||
|
builder.append(" \"s3:GetBucketLocation\",\n");
|
||||||
|
builder.append(" \"s3:ListBucket\"\n");
|
||||||
|
builder.append(" ],\n");
|
||||||
|
builder.append(" \"Effect\": \"Allow\",\n");
|
||||||
|
builder.append(" \"Principal\": \"*\",\n");
|
||||||
|
builder.append(" \"Resource\": \"arn:aws:s3:::"+bucketName+"\"\n");
|
||||||
|
builder.append(" },\n");
|
||||||
|
builder.append(" {\n");
|
||||||
|
builder.append(" \"Action\": \"s3:GetObject\",\n");
|
||||||
|
builder.append(" \"Effect\": \"Allow\",\n");
|
||||||
|
builder.append(" \"Principal\": \"*\",\n");
|
||||||
|
builder.append(" \"Resource\": \"arn:aws:s3:::"+bucketName+"/*\"\n");
|
||||||
|
builder.append(" }\n");
|
||||||
|
builder.append(" ],\n");
|
||||||
|
builder.append(" \"Version\": \"2012-10-17\"\n");
|
||||||
|
builder.append("}\n");
|
||||||
|
|
||||||
|
String publicPolicy = builder.toString();
|
||||||
|
|
||||||
|
//ToDo Support custom policy
|
||||||
|
String policyConfig = (policy.equalsIgnoreCase("public"))? publicPolicy : privatePolicy;
|
||||||
|
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
try {
|
||||||
|
minioClient.setBucketPolicy(
|
||||||
|
SetBucketPolicyArgs.builder().bucket(bucketName).config(policyConfig).build());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BucketPolicy getBucketPolicy(String bucketName, long storeId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteBucketPolicy(String bucketName, long storeId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean createUser(long accountId, long storeId) {
|
||||||
|
Account account = _accountDao.findById(accountId);
|
||||||
|
MinioAdminClient minioAdminClient = getMinIOAdminClient(storeId);
|
||||||
|
String accessKey = "acs-"+account.getAccountName();
|
||||||
|
// Check user exists
|
||||||
|
try {
|
||||||
|
UserInfo userInfo = minioAdminClient.getUserInfo(accessKey);
|
||||||
|
if(userInfo != null) {
|
||||||
|
s_logger.debug("User already exists in MinIO store: "+accessKey);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.debug("User does not exist. Creating user: "+accessKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyGenerator generator = null;
|
||||||
|
try {
|
||||||
|
generator = KeyGenerator.getInstance("HmacSHA1");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
SecretKey key = generator.generateKey();
|
||||||
|
String secretKey = Base64.encodeBase64URLSafeString(key.getEncoded());
|
||||||
|
try {
|
||||||
|
minioAdminClient.addUser(accessKey, UserInfo.Status.ENABLED, secretKey, "", new ArrayList<String>());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
// Store user credentials
|
||||||
|
Map<String, String> details = new HashMap<>();
|
||||||
|
details.put(MINIO_ACCESS_KEY, accessKey);
|
||||||
|
details.put(MINIO_SECRET_KEY, secretKey);
|
||||||
|
_accountDetailsDao.persist(accountId, details);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBucketEncryption(String bucketName, long storeId) {
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
try {
|
||||||
|
minioClient.setBucketEncryption(SetBucketEncryptionArgs.builder()
|
||||||
|
.bucket(bucketName)
|
||||||
|
.config(SseConfiguration.newConfigWithSseS3Rule())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucketEncryption(String bucketName, long storeId) {
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
try {
|
||||||
|
minioClient.deleteBucketEncryption(DeleteBucketEncryptionArgs.builder()
|
||||||
|
.bucket(bucketName)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBucketVersioning(String bucketName, long storeId) {
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
try {
|
||||||
|
minioClient.setBucketVersioning(SetBucketVersioningArgs.builder()
|
||||||
|
.bucket(bucketName)
|
||||||
|
.config(new VersioningConfiguration(VersioningConfiguration.Status.ENABLED, null))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucketVersioning(String bucketName, long storeId) {
|
||||||
|
MinioClient minioClient = getMinIOClient(storeId);
|
||||||
|
try {
|
||||||
|
minioClient.setBucketVersioning(SetBucketVersioningArgs.builder()
|
||||||
|
.bucket(bucketName)
|
||||||
|
.config(new VersioningConfiguration(VersioningConfiguration.Status.SUSPENDED, null))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBucketQuota(String bucketName, long storeId, long size) {
|
||||||
|
|
||||||
|
MinioAdminClient minioAdminClient = getMinIOAdminClient(storeId);
|
||||||
|
try {
|
||||||
|
minioAdminClient.setBucketQuota(bucketName, size, QuotaUnit.GB);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Long> getAllBucketsUsage(long storeId) {
|
||||||
|
MinioAdminClient minioAdminClient = getMinIOAdminClient(storeId);
|
||||||
|
try {
|
||||||
|
DataUsageInfo dataUsageInfo = minioAdminClient.getDataUsageInfo();
|
||||||
|
return dataUsageInfo.bucketsSizes();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MinioClient getMinIOClient(long storeId) {
|
||||||
|
ObjectStoreVO store = _storeDao.findById(storeId);
|
||||||
|
Map<String, String> storeDetails = _storeDetailsDao.getDetails(storeId);
|
||||||
|
String url = store.getUrl();
|
||||||
|
String accessKey = storeDetails.get(ACCESS_KEY);
|
||||||
|
String secretKey = storeDetails.get(SECRET_KEY);
|
||||||
|
MinioClient minioClient =
|
||||||
|
MinioClient.builder()
|
||||||
|
.endpoint(url)
|
||||||
|
.credentials(accessKey,secretKey)
|
||||||
|
.build();
|
||||||
|
if(minioClient == null){
|
||||||
|
throw new CloudRuntimeException("Error while creating MinIO client");
|
||||||
|
}
|
||||||
|
return minioClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MinioAdminClient getMinIOAdminClient(long storeId) {
|
||||||
|
ObjectStoreVO store = _storeDao.findById(storeId);
|
||||||
|
Map<String, String> storeDetails = _storeDetailsDao.getDetails(storeId);
|
||||||
|
String url = store.getUrl();
|
||||||
|
String accessKey = storeDetails.get(ACCESS_KEY);
|
||||||
|
String secretKey = storeDetails.get(SECRET_KEY);
|
||||||
|
MinioAdminClient minioAdminClient =
|
||||||
|
MinioAdminClient.builder()
|
||||||
|
.endpoint(url)
|
||||||
|
.credentials(accessKey,secretKey)
|
||||||
|
.build();
|
||||||
|
if(minioAdminClient == null){
|
||||||
|
throw new CloudRuntimeException("Error while creating MinIO client");
|
||||||
|
}
|
||||||
|
return minioAdminClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,129 @@
|
|||||||
|
// 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.lifecycle;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.StoragePoolInfo;
|
||||||
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreHelper;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.storage.object.store.lifecycle.ObjectStoreLifeCycle;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MinIOObjectStoreLifeCycleImpl implements ObjectStoreLifeCycle {
|
||||||
|
|
||||||
|
private static final Logger s_logger = Logger.getLogger(MinIOObjectStoreLifeCycleImpl.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ObjectStoreHelper objectStoreHelper;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreProviderManager objectStoreMgr;
|
||||||
|
|
||||||
|
public MinIOObjectStoreLifeCycleImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public DataStore initialize(Map<String, Object> dsInfos) {
|
||||||
|
|
||||||
|
String url = (String)dsInfos.get("url");
|
||||||
|
String name = (String)dsInfos.get("name");
|
||||||
|
String providerName = (String)dsInfos.get("providerName");
|
||||||
|
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
|
||||||
|
if(details == null){
|
||||||
|
throw new CloudRuntimeException("MinIO credentials are missing");
|
||||||
|
}
|
||||||
|
String accessKey = details.get("accesskey");
|
||||||
|
String secretKey = details.get("secretkey");
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> objectStoreParameters = new HashMap();
|
||||||
|
objectStoreParameters.put("name", name);
|
||||||
|
objectStoreParameters.put("url", url);
|
||||||
|
|
||||||
|
objectStoreParameters.put("providerName", providerName);
|
||||||
|
objectStoreParameters.put("accesskey", accessKey);
|
||||||
|
objectStoreParameters.put("secretkey", secretKey);
|
||||||
|
|
||||||
|
//check credentials
|
||||||
|
MinioClient minioClient =
|
||||||
|
MinioClient.builder()
|
||||||
|
.endpoint(url)
|
||||||
|
.credentials(accessKey,secretKey)
|
||||||
|
.build();
|
||||||
|
try {
|
||||||
|
// Test connection by listing buckets
|
||||||
|
minioClient.listBuckets();
|
||||||
|
s_logger.debug("Successfully connected to MinIO EndPoint: "+url);
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.debug("Error while initializing MinIO Object Store: "+e.getMessage());
|
||||||
|
throw new RuntimeException("Error while initializing MinIO Object Store. Invalid credentials or URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectStoreVO objectStore = objectStoreHelper.createObjectStore(objectStoreParameters, details);
|
||||||
|
return objectStoreMgr.getObjectStore(objectStore.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attachCluster(DataStore store, ClusterScope scope) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean maintain(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean cancelMaintain(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteDataStore(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle#migrateToObjectStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean migrateToObjectStore(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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.provider;
|
||||||
|
|
||||||
|
import com.cloud.utils.component.ComponentContext;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectStoreProvider;
|
||||||
|
import org.apache.cloudstack.storage.datastore.driver.MinIOObjectStoreDriverImpl;
|
||||||
|
import org.apache.cloudstack.storage.datastore.lifecycle.MinIOObjectStoreLifeCycleImpl;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreHelper;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.storage.object.store.lifecycle.ObjectStoreLifeCycle;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MinIOObjectStoreProviderImpl implements ObjectStoreProvider {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ObjectStoreProviderManager storeMgr;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreHelper helper;
|
||||||
|
|
||||||
|
private final String providerName = "MinIO";
|
||||||
|
protected ObjectStoreLifeCycle lifeCycle;
|
||||||
|
protected ObjectStoreDriver driver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreLifeCycle getDataStoreLifeCycle() {
|
||||||
|
return lifeCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(Map<String, Object> params) {
|
||||||
|
lifeCycle = ComponentContext.inject(MinIOObjectStoreLifeCycleImpl.class);
|
||||||
|
driver = ComponentContext.inject(MinIOObjectStoreDriverImpl.class);
|
||||||
|
storeMgr.registerDriver(this.getName(), driver);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreDriver getDataStoreDriver() {
|
||||||
|
return this.driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HypervisorHostListener getHostListener() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<DataStoreProviderType> getTypes() {
|
||||||
|
Set<DataStoreProviderType> types = new HashSet<DataStoreProviderType>();
|
||||||
|
types.add(DataStoreProviderType.OBJECT);
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
# 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.
|
||||||
|
name=storage-object-minio
|
||||||
|
parent=storage
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||||
|
http://www.springframework.org/schema/context
|
||||||
|
http://www.springframework.org/schema/context/spring-context.xsd"
|
||||||
|
>
|
||||||
|
<bean id="minioStoreProviderImpl"
|
||||||
|
class="org.apache.cloudstack.storage.datastore.provider.MinIOObjectStoreProviderImpl" />
|
||||||
|
</beans>
|
||||||
@ -0,0 +1,122 @@
|
|||||||
|
// 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.driver;
|
||||||
|
|
||||||
|
import com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
|
import com.cloud.user.AccountDetailVO;
|
||||||
|
import com.cloud.user.AccountDetailsDao;
|
||||||
|
import com.cloud.user.AccountVO;
|
||||||
|
import com.cloud.user.dao.AccountDao;
|
||||||
|
import io.minio.BucketExistsArgs;
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import io.minio.RemoveBucketArgs;
|
||||||
|
import io.minio.admin.MinioAdminClient;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.any;
|
||||||
|
import static org.mockito.Mockito.anyLong;
|
||||||
|
import static org.mockito.Mockito.anyString;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class MinIOObjectStoreDriverImplTest {
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
MinIOObjectStoreDriverImpl minioObjectStoreDriverImpl = new MinIOObjectStoreDriverImpl();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
MinioClient minioClient;
|
||||||
|
@Mock
|
||||||
|
MinioAdminClient minioAdminClient;
|
||||||
|
@Mock
|
||||||
|
ObjectStoreDao objectStoreDao;
|
||||||
|
@Mock
|
||||||
|
ObjectStoreVO objectStoreVO;
|
||||||
|
@Mock
|
||||||
|
ObjectStoreDetailsDao objectStoreDetailsDao;
|
||||||
|
@Mock
|
||||||
|
AccountDao accountDao;
|
||||||
|
@Mock
|
||||||
|
BucketDao bucketDao;
|
||||||
|
@Mock
|
||||||
|
AccountVO account;
|
||||||
|
@Mock
|
||||||
|
AccountDetailsDao accountDetailsDao;
|
||||||
|
|
||||||
|
Bucket bucket;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
minioObjectStoreDriverImpl._storeDao = objectStoreDao;
|
||||||
|
minioObjectStoreDriverImpl._storeDetailsDao = objectStoreDetailsDao;
|
||||||
|
minioObjectStoreDriverImpl._accountDao = accountDao;
|
||||||
|
minioObjectStoreDriverImpl._bucketDao = bucketDao;
|
||||||
|
minioObjectStoreDriverImpl._accountDetailsDao = accountDetailsDao;
|
||||||
|
bucket = new BucketVO();
|
||||||
|
bucket.setName("test-bucket");
|
||||||
|
when(objectStoreVO.getUrl()).thenReturn("http://localhost:9000");
|
||||||
|
when(objectStoreDao.findById(any())).thenReturn(objectStoreVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateBucket() throws Exception {
|
||||||
|
doReturn(minioClient).when(minioObjectStoreDriverImpl).getMinIOClient(anyLong());
|
||||||
|
doReturn(minioAdminClient).when(minioObjectStoreDriverImpl).getMinIOAdminClient(anyLong());
|
||||||
|
when(bucketDao.listByObjectStoreIdAndAccountId(anyLong(), anyLong())).thenReturn(new ArrayList<BucketVO>());
|
||||||
|
when(account.getAccountName()).thenReturn("admin");
|
||||||
|
when(accountDao.findById(anyLong())).thenReturn(account);
|
||||||
|
when(accountDetailsDao.findDetail(anyLong(),anyString())).
|
||||||
|
thenReturn(new AccountDetailVO(1L, "abc","def"));
|
||||||
|
when(bucketDao.findById(anyLong())).thenReturn(new BucketVO());
|
||||||
|
Bucket bucketRet = minioObjectStoreDriverImpl.createBucket(bucket, false);
|
||||||
|
assertEquals(bucketRet.getName(), bucket.getName());
|
||||||
|
verify(minioClient, times(1)).bucketExists(any());
|
||||||
|
verify(minioClient, times(1)).makeBucket(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteBucket() throws Exception {
|
||||||
|
String bucketName = "test-bucket";
|
||||||
|
doReturn(minioClient).when(minioObjectStoreDriverImpl).getMinIOClient(anyLong());
|
||||||
|
when(minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())).thenReturn(true);
|
||||||
|
doNothing().when(minioClient).removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
|
||||||
|
boolean success = minioObjectStoreDriverImpl.deleteBucket(bucketName, 1L);
|
||||||
|
assertTrue(success);
|
||||||
|
verify(minioClient, times(1)).bucketExists(any());
|
||||||
|
verify(minioClient, times(1)).removeBucket(any());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
// 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.provider;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider.DataStoreProviderType;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class MinIOObjectStoreProviderImplTest {
|
||||||
|
|
||||||
|
private MinIOObjectStoreProviderImpl minioObjectStoreProviderImpl;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
minioObjectStoreProviderImpl = new MinIOObjectStoreProviderImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetName() {
|
||||||
|
String name = minioObjectStoreProviderImpl.getName();
|
||||||
|
assertEquals("MinIO", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTypes() {
|
||||||
|
Set<DataStoreProviderType> types = minioObjectStoreProviderImpl.getTypes();
|
||||||
|
assertEquals(1, types.size());
|
||||||
|
assertEquals("OBJECT", types.toArray()[0].toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
57
plugins/storage/object/simulator/pom.xml
Normal file
57
plugins/storage/object/simulator/pom.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>cloud-plugin-storage-object-simulator</artifactId>
|
||||||
|
<name>Apache CloudStack Plugin - Simulator object storage provider</name>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloudstack-plugins</artifactId>
|
||||||
|
<version>4.19.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-storage-object</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cloudstack</groupId>
|
||||||
|
<artifactId>cloud-engine-schema</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId>
|
||||||
|
<version>8.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio-admin</artifactId>
|
||||||
|
<version>8.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* 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.driver;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.model.AccessControlList;
|
||||||
|
import com.amazonaws.services.s3.model.BucketPolicy;
|
||||||
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.BaseObjectStoreDriverImpl;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SimulatorObjectStoreDriverImpl extends BaseObjectStoreDriverImpl {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(SimulatorObjectStoreDriverImpl.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ObjectStoreDao _storeDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
BucketDao _bucketDao;
|
||||||
|
|
||||||
|
private static final String ACCESS_KEY = "accesskey";
|
||||||
|
private static final String SECRET_KEY = "secretkey";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreTO getStoreTO(DataStore store) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bucket createBucket(Bucket bucket, boolean objectLock) {
|
||||||
|
String bucketName = bucket.getName();
|
||||||
|
long storeId = bucket.getObjectStoreId();
|
||||||
|
ObjectStoreVO store = _storeDao.findById(storeId);
|
||||||
|
BucketVO bucketVO = _bucketDao.findById(bucket.getId());
|
||||||
|
bucketVO.setAccessKey(ACCESS_KEY);
|
||||||
|
bucketVO.setSecretKey(SECRET_KEY);
|
||||||
|
bucketVO.setBucketURL(store.getUrl()+"/"+bucketName);
|
||||||
|
_bucketDao.update(bucket.getId(), bucketVO);
|
||||||
|
return bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Bucket> listBuckets(long storeId) {
|
||||||
|
List<Bucket> bucketsList = new ArrayList<>();
|
||||||
|
return bucketsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucket(String bucketName, long storeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessControlList getBucketAcl(String bucketName, long storeId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBucketAcl(String bucketName, AccessControlList acl, long storeId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBucketPolicy(String bucketName, String policy, long storeId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BucketPolicy getBucketPolicy(String bucketName, long storeId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteBucketPolicy(String bucketName, long storeId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean createUser(long accountId, long storeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBucketEncryption(String bucketName, long storeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucketEncryption(String bucketName, long storeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBucketVersioning(String bucketName, long storeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteBucketVersioning(String bucketName, long storeId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBucketQuota(String bucketName, long storeId, long size) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Long> getAllBucketsUsage(long storeId) {
|
||||||
|
return new HashMap<String, Long>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
// 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.lifecycle;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.StoragePoolInfo;
|
||||||
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
|
import com.cloud.resource.Discoverer;
|
||||||
|
import com.cloud.resource.ResourceManager;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreHelper;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.storage.object.store.lifecycle.ObjectStoreLifeCycle;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SimulatorObjectStoreLifeCycleImpl implements ObjectStoreLifeCycle {
|
||||||
|
|
||||||
|
private static final Logger s_logger = Logger.getLogger(SimulatorObjectStoreLifeCycleImpl.class);
|
||||||
|
@Inject
|
||||||
|
protected ResourceManager _resourceMgr;
|
||||||
|
@Inject
|
||||||
|
protected ObjectStoreDao objectStoreDao;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreHelper objectStoreHelper;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreProviderManager objectStoreMgr;
|
||||||
|
|
||||||
|
protected List<? extends Discoverer> _discoverers;
|
||||||
|
|
||||||
|
public List<? extends Discoverer> getDiscoverers() {
|
||||||
|
return _discoverers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiscoverers(List<? extends Discoverer> discoverers) {
|
||||||
|
this._discoverers = discoverers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimulatorObjectStoreLifeCycleImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public DataStore initialize(Map<String, Object> dsInfos) {
|
||||||
|
|
||||||
|
String url = (String)dsInfos.get("url");
|
||||||
|
String name = (String)dsInfos.get("name");
|
||||||
|
String providerName = (String)dsInfos.get("providerName");
|
||||||
|
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
|
||||||
|
|
||||||
|
Map<String, Object> objectStoreParameters = new HashMap();
|
||||||
|
objectStoreParameters.put("name", name);
|
||||||
|
objectStoreParameters.put("url", url);
|
||||||
|
objectStoreParameters.put("providerName", providerName);
|
||||||
|
|
||||||
|
ObjectStoreVO ids = objectStoreHelper.createObjectStore(objectStoreParameters, details);
|
||||||
|
return objectStoreMgr.getObjectStore(ids.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attachCluster(DataStore store, ClusterScope scope) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean maintain(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean cancelMaintain(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteDataStore(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle#migrateToObjectStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean migrateToObjectStore(DataStore store) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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.provider;
|
||||||
|
|
||||||
|
import com.cloud.utils.component.ComponentContext;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectStoreProvider;
|
||||||
|
import org.apache.cloudstack.storage.datastore.driver.SimulatorObjectStoreDriverImpl;
|
||||||
|
import org.apache.cloudstack.storage.datastore.lifecycle.SimulatorObjectStoreLifeCycleImpl;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreDriver;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreHelper;
|
||||||
|
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.storage.object.store.lifecycle.ObjectStoreLifeCycle;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SimulatorObjectStoreProviderImpl implements ObjectStoreProvider {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ObjectStoreProviderManager storeMgr;
|
||||||
|
@Inject
|
||||||
|
ObjectStoreHelper helper;
|
||||||
|
|
||||||
|
private final String providerName = "Simulator";
|
||||||
|
protected ObjectStoreLifeCycle lifeCycle;
|
||||||
|
protected ObjectStoreDriver driver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreLifeCycle getDataStoreLifeCycle() {
|
||||||
|
return lifeCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(Map<String, Object> params) {
|
||||||
|
lifeCycle = ComponentContext.inject(SimulatorObjectStoreLifeCycleImpl.class);
|
||||||
|
driver = ComponentContext.inject(SimulatorObjectStoreDriverImpl.class);
|
||||||
|
storeMgr.registerDriver(this.getName(), driver);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStoreDriver getDataStoreDriver() {
|
||||||
|
return this.driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HypervisorHostListener getHostListener() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<DataStoreProviderType> getTypes() {
|
||||||
|
Set<DataStoreProviderType> types = new HashSet<DataStoreProviderType>();
|
||||||
|
types.add(DataStoreProviderType.OBJECT);
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
# 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.
|
||||||
|
name=storage-object-simulator
|
||||||
|
parent=storage
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||||
|
http://www.springframework.org/schema/context
|
||||||
|
http://www.springframework.org/schema/context/spring-context.xsd"
|
||||||
|
>
|
||||||
|
<bean id="simulatorObjectStoreProviderImpl"
|
||||||
|
class="org.apache.cloudstack.storage.datastore.provider.SimulatorObjectStoreProviderImpl" />
|
||||||
|
</beans>
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
// 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.provider;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class SimulatorObjectStoreProviderImplTest {
|
||||||
|
|
||||||
|
private SimulatorObjectStoreProviderImpl simulatorObjectStoreProviderImpl;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
simulatorObjectStoreProviderImpl = new SimulatorObjectStoreProviderImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetName() {
|
||||||
|
String name = simulatorObjectStoreProviderImpl.getName();
|
||||||
|
assertEquals("Simulator", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTypes() {
|
||||||
|
Set<DataStoreProvider.DataStoreProviderType> types = simulatorObjectStoreProviderImpl.getTypes();
|
||||||
|
assertEquals(1, types.size());
|
||||||
|
assertEquals("OBJECT", types.toArray()[0].toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -294,6 +294,7 @@ import com.cloud.storage.Volume;
|
|||||||
import com.cloud.storage.Volume.Type;
|
import com.cloud.storage.Volume.Type;
|
||||||
import com.cloud.storage.VolumeStats;
|
import com.cloud.storage.VolumeStats;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
import com.cloud.storage.dao.DiskOfferingDao;
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||||
import com.cloud.storage.dao.GuestOSDao;
|
import com.cloud.storage.dao.GuestOSDao;
|
||||||
@ -349,6 +350,10 @@ import com.cloud.vm.dao.VMInstanceDao;
|
|||||||
import com.cloud.vm.snapshot.VMSnapshot;
|
import com.cloud.vm.snapshot.VMSnapshot;
|
||||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
|
||||||
public class ApiDBUtils {
|
public class ApiDBUtils {
|
||||||
private static ManagementServer s_ms;
|
private static ManagementServer s_ms;
|
||||||
static AsyncJobManager s_asyncMgr;
|
static AsyncJobManager s_asyncMgr;
|
||||||
@ -481,6 +486,9 @@ public class ApiDBUtils {
|
|||||||
static NicDao s_nicDao;
|
static NicDao s_nicDao;
|
||||||
static ResourceManagerUtil s_resourceManagerUtil;
|
static ResourceManagerUtil s_resourceManagerUtil;
|
||||||
static SnapshotPolicyDetailsDao s_snapshotPolicyDetailsDao;
|
static SnapshotPolicyDetailsDao s_snapshotPolicyDetailsDao;
|
||||||
|
static ObjectStoreDao s_objectStoreDao;
|
||||||
|
|
||||||
|
static BucketDao s_bucketDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ManagementServer ms;
|
private ManagementServer ms;
|
||||||
@ -740,6 +748,11 @@ public class ApiDBUtils {
|
|||||||
@Inject
|
@Inject
|
||||||
SnapshotPolicyDetailsDao snapshotPolicyDetailsDao;
|
SnapshotPolicyDetailsDao snapshotPolicyDetailsDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ObjectStoreDao objectStoreDao;
|
||||||
|
@Inject
|
||||||
|
private BucketDao bucketDao;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
void init() {
|
void init() {
|
||||||
s_ms = ms;
|
s_ms = ms;
|
||||||
@ -871,6 +884,8 @@ public class ApiDBUtils {
|
|||||||
s_backupOfferingDao = backupOfferingDao;
|
s_backupOfferingDao = backupOfferingDao;
|
||||||
s_resourceIconDao = resourceIconDao;
|
s_resourceIconDao = resourceIconDao;
|
||||||
s_resourceManagerUtil = resourceManagerUtil;
|
s_resourceManagerUtil = resourceManagerUtil;
|
||||||
|
s_objectStoreDao = objectStoreDao;
|
||||||
|
s_bucketDao = bucketDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////
|
||||||
@ -2208,4 +2223,12 @@ public class ApiDBUtils {
|
|||||||
public static NicSecondaryIpVO findSecondaryIpByIp4AddressAndNetworkId(String ip4Address, long networkId) {
|
public static NicSecondaryIpVO findSecondaryIpByIp4AddressAndNetworkId(String ip4Address, long networkId) {
|
||||||
return s_nicSecondaryIpDao.findByIp4AddressAndNetworkId(ip4Address, networkId);
|
return s_nicSecondaryIpDao.findByIp4AddressAndNetworkId(ip4Address, networkId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ObjectStoreResponse newObjectStoreResponse(ObjectStoreVO store) {
|
||||||
|
return s_objectStoreDao.newObjectStoreResponse(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ObjectStoreResponse fillObjectStoreDetails(ObjectStoreResponse storeData, ObjectStoreVO store) {
|
||||||
|
return s_objectStoreDao.setObjectStoreResponse(storeData, store);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,8 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
|
import com.cloud.storage.BucketVO;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||||
@ -63,6 +65,7 @@ import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
|
|||||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||||
import org.apache.cloudstack.api.response.BackupResponse;
|
import org.apache.cloudstack.api.response.BackupResponse;
|
||||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
import org.apache.cloudstack.api.response.CapabilityResponse;
|
import org.apache.cloudstack.api.response.CapabilityResponse;
|
||||||
import org.apache.cloudstack.api.response.CapacityResponse;
|
import org.apache.cloudstack.api.response.CapacityResponse;
|
||||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||||
@ -119,6 +122,7 @@ import org.apache.cloudstack.api.response.NetworkResponse;
|
|||||||
import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
|
import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
|
||||||
import org.apache.cloudstack.api.response.NicResponse;
|
import org.apache.cloudstack.api.response.NicResponse;
|
||||||
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
|
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.OvsProviderResponse;
|
import org.apache.cloudstack.api.response.OvsProviderResponse;
|
||||||
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
||||||
import org.apache.cloudstack.api.response.PodResponse;
|
import org.apache.cloudstack.api.response.PodResponse;
|
||||||
@ -196,10 +200,14 @@ import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
|
|||||||
import org.apache.cloudstack.region.PortableIp;
|
import org.apache.cloudstack.region.PortableIp;
|
||||||
import org.apache.cloudstack.region.PortableIpRange;
|
import org.apache.cloudstack.region.PortableIpRange;
|
||||||
import org.apache.cloudstack.region.Region;
|
import org.apache.cloudstack.region.Region;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
import org.apache.cloudstack.storage.object.Bucket;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
import org.apache.cloudstack.usage.Usage;
|
import org.apache.cloudstack.usage.Usage;
|
||||||
import org.apache.cloudstack.usage.UsageService;
|
import org.apache.cloudstack.usage.UsageService;
|
||||||
import org.apache.cloudstack.usage.UsageTypes;
|
import org.apache.cloudstack.usage.UsageTypes;
|
||||||
@ -263,7 +271,6 @@ import com.cloud.gpu.GPU;
|
|||||||
import com.cloud.host.ControlState;
|
import com.cloud.host.ControlState;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.hypervisor.Hypervisor;
|
|
||||||
import com.cloud.hypervisor.HypervisorCapabilities;
|
import com.cloud.hypervisor.HypervisorCapabilities;
|
||||||
import com.cloud.network.GuestVlan;
|
import com.cloud.network.GuestVlan;
|
||||||
import com.cloud.network.GuestVlanRange;
|
import com.cloud.network.GuestVlanRange;
|
||||||
@ -470,6 +477,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
@Inject
|
@Inject
|
||||||
UserDataDao userDataDao;
|
UserDataDao userDataDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ObjectStoreDao _objectStoreDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserResponse createUserResponse(User user) {
|
public UserResponse createUserResponse(User user) {
|
||||||
UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
|
UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
|
||||||
@ -4309,6 +4319,10 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
}
|
}
|
||||||
usageRecResponse.setDescription(builder.toString());
|
usageRecResponse.setDescription(builder.toString());
|
||||||
}
|
}
|
||||||
|
} else if (usageRecord.getUsageType() == UsageTypes.BUCKET) {
|
||||||
|
BucketVO bucket = _entityMgr.findByIdIncludingRemoved(BucketVO.class, usageRecord.getUsageId().toString());
|
||||||
|
usageRecResponse.setUsageId(bucket.getUuid());
|
||||||
|
usageRecResponse.setResourceName(bucket.getName());
|
||||||
}
|
}
|
||||||
if(resourceTagResponseMap != null && resourceTagResponseMap.get(resourceId + ":" + resourceType) != null) {
|
if(resourceTagResponseMap != null && resourceTagResponseMap.get(resourceId + ":" + resourceType) != null) {
|
||||||
usageRecResponse.setTags(resourceTagResponseMap.get(resourceId + ":" + resourceType));
|
usageRecResponse.setTags(resourceTagResponseMap.get(resourceId + ":" + resourceType));
|
||||||
@ -5109,4 +5123,40 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||||||
|
|
||||||
return quarantinedIpsResponse;
|
return quarantinedIpsResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObjectStoreResponse createObjectStoreResponse(ObjectStore os) {
|
||||||
|
ObjectStoreResponse objectStoreResponse = new ObjectStoreResponse();
|
||||||
|
objectStoreResponse.setId(os.getUuid());
|
||||||
|
objectStoreResponse.setName(os.getName());
|
||||||
|
objectStoreResponse.setProviderName(os.getProviderName());
|
||||||
|
objectStoreResponse.setObjectName("objectstore");
|
||||||
|
return objectStoreResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BucketResponse createBucketResponse(Bucket bucket) {
|
||||||
|
BucketResponse bucketResponse = new BucketResponse();
|
||||||
|
bucketResponse.setName(bucket.getName());
|
||||||
|
bucketResponse.setId(bucket.getUuid());
|
||||||
|
bucketResponse.setCreated(bucket.getCreated());
|
||||||
|
bucketResponse.setState(bucket.getState());
|
||||||
|
bucketResponse.setSize(bucket.getSize());
|
||||||
|
if(bucket.getQuota() != null) {
|
||||||
|
bucketResponse.setQuota(bucket.getQuota());
|
||||||
|
}
|
||||||
|
bucketResponse.setVersioning(bucket.isVersioning());
|
||||||
|
bucketResponse.setEncryption(bucket.isEncryption());
|
||||||
|
bucketResponse.setObjectLock(bucket.isObjectLock());
|
||||||
|
bucketResponse.setPolicy(bucket.getPolicy());
|
||||||
|
bucketResponse.setBucketURL(bucket.getBucketURL());
|
||||||
|
bucketResponse.setAccessKey(bucket.getAccessKey());
|
||||||
|
bucketResponse.setSecretKey(bucket.getSecretKey());
|
||||||
|
ObjectStoreVO objectStoreVO = _objectStoreDao.findById(bucket.getObjectStoreId());
|
||||||
|
bucketResponse.setObjectStoragePoolId(objectStoreVO.getUuid());
|
||||||
|
bucketResponse.setObjectStoragePool(objectStoreVO.getName());
|
||||||
|
bucketResponse.setObjectName("bucket");
|
||||||
|
bucketResponse.setProvider(objectStoreVO.getProviderName());
|
||||||
|
populateAccount(bucketResponse, bucket.getAccountId());
|
||||||
|
return bucketResponse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,6 +83,7 @@ import org.apache.cloudstack.api.command.admin.router.GetRouterHealthCheckResult
|
|||||||
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
|
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.snapshot.ListSnapshotsCmdByAdmin;
|
import org.apache.cloudstack.api.command.admin.snapshot.ListSnapshotsCmdByAdmin;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.ListObjectStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
|
||||||
@ -126,6 +127,7 @@ import org.apache.cloudstack.api.response.InstanceGroupResponse;
|
|||||||
import org.apache.cloudstack.api.response.IpQuarantineResponse;
|
import org.apache.cloudstack.api.response.IpQuarantineResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
import org.apache.cloudstack.api.response.ManagementServerResponse;
|
import org.apache.cloudstack.api.response.ManagementServerResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||||
@ -156,6 +158,8 @@ import org.apache.cloudstack.framework.config.Configurable;
|
|||||||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
|
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
|
||||||
import org.apache.cloudstack.query.QueryService;
|
import org.apache.cloudstack.query.QueryService;
|
||||||
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||||
@ -261,6 +265,7 @@ import com.cloud.server.ResourceTag.ResourceObjectType;
|
|||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||||
|
import com.cloud.storage.BucketVO;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
@ -275,6 +280,7 @@ import com.cloud.storage.VMTemplateVO;
|
|||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.VolumeApiServiceImpl;
|
import com.cloud.storage.VolumeApiServiceImpl;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
import com.cloud.storage.dao.DiskOfferingDao;
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import com.cloud.storage.dao.StoragePoolTagsDao;
|
import com.cloud.storage.dao.StoragePoolTagsDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
@ -310,6 +316,8 @@ import com.cloud.vm.VmDetailConstants;
|
|||||||
import com.cloud.vm.dao.DomainRouterDao;
|
import com.cloud.vm.dao.DomainRouterDao;
|
||||||
import com.cloud.vm.dao.UserVmDao;
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.ListBucketsCmd;
|
||||||
|
import org.apache.cloudstack.api.response.BucketResponse;
|
||||||
|
|
||||||
import static com.cloud.vm.VmDetailConstants.SSH_PUBLIC_KEY;
|
import static com.cloud.vm.VmDetailConstants.SSH_PUBLIC_KEY;
|
||||||
|
|
||||||
@ -543,6 +551,12 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Inject
|
@Inject
|
||||||
private SnapshotJoinDao snapshotJoinDao;
|
private SnapshotJoinDao snapshotJoinDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ObjectStoreDao objectStoreDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BucketDao bucketDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
EntityManager entityManager;
|
EntityManager entityManager;
|
||||||
|
|
||||||
@ -5030,6 +5044,158 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
return new Pair<>(snapshots, count);
|
return new Pair<>(snapshots, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListResponse<ObjectStoreResponse> searchForObjectStores(ListObjectStoragePoolsCmd cmd) {
|
||||||
|
Pair<List<ObjectStoreVO>, Integer> result = searchForObjectStoresInternal(cmd);
|
||||||
|
ListResponse<ObjectStoreResponse> response = new ListResponse<ObjectStoreResponse>();
|
||||||
|
|
||||||
|
List<ObjectStoreResponse> poolResponses = ViewResponseHelper.createObjectStoreResponse(result.first().toArray(new ObjectStoreVO[result.first().size()]));
|
||||||
|
response.setResponses(poolResponses, result.second());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<List<ObjectStoreVO>, Integer> searchForObjectStoresInternal(ListObjectStoragePoolsCmd cmd) {
|
||||||
|
|
||||||
|
Object id = cmd.getId();
|
||||||
|
Object name = cmd.getStoreName();
|
||||||
|
String provider = cmd.getProvider();
|
||||||
|
Object keyword = cmd.getKeyword();
|
||||||
|
Long startIndex = cmd.getStartIndex();
|
||||||
|
Long pageSize = cmd.getPageSizeVal();
|
||||||
|
|
||||||
|
Filter searchFilter = new Filter(ObjectStoreVO.class, "id", Boolean.TRUE, startIndex, pageSize);
|
||||||
|
|
||||||
|
SearchBuilder<ObjectStoreVO> sb = objectStoreDao.createSearchBuilder();
|
||||||
|
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
|
||||||
|
// ids
|
||||||
|
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
||||||
|
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
|
sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ);
|
||||||
|
|
||||||
|
SearchCriteria<ObjectStoreVO> sc = sb.create();
|
||||||
|
|
||||||
|
if (keyword != null) {
|
||||||
|
SearchCriteria<ObjectStoreVO> ssc = objectStoreDao.createSearchCriteria();
|
||||||
|
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||||
|
ssc.addOr("providerName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||||
|
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
sc.setParameters("id", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name != null) {
|
||||||
|
sc.setParameters("name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provider != null) {
|
||||||
|
sc.setParameters("provider", provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
// search Store details by ids
|
||||||
|
Pair<List<ObjectStoreVO>, Integer> uniqueStorePair = objectStoreDao.searchAndCount(sc, searchFilter);
|
||||||
|
Integer count = uniqueStorePair.second();
|
||||||
|
if (count.intValue() == 0) {
|
||||||
|
// empty result
|
||||||
|
return uniqueStorePair;
|
||||||
|
}
|
||||||
|
List<ObjectStoreVO> uniqueStores = uniqueStorePair.first();
|
||||||
|
Long[] osIds = new Long[uniqueStores.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (ObjectStoreVO v : uniqueStores) {
|
||||||
|
osIds[i++] = v.getId();
|
||||||
|
}
|
||||||
|
List<ObjectStoreVO> objectStores = objectStoreDao.searchByIds(osIds);
|
||||||
|
return new Pair<>(objectStores, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListResponse<BucketResponse> searchForBuckets(ListBucketsCmd listBucketsCmd) {
|
||||||
|
List<BucketVO> buckets = searchForBucketsInternal(listBucketsCmd);
|
||||||
|
List<BucketResponse> bucketResponses = new ArrayList<>();
|
||||||
|
for (BucketVO bucket : buckets) {
|
||||||
|
bucketResponses.add(responseGenerator.createBucketResponse(bucket));
|
||||||
|
}
|
||||||
|
ListResponse<BucketResponse> response = new ListResponse<>();
|
||||||
|
response.setResponses(bucketResponses, bucketResponses.size());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BucketVO> searchForBucketsInternal(ListBucketsCmd cmd) {
|
||||||
|
|
||||||
|
Long id = cmd.getId();
|
||||||
|
String name = cmd.getBucketName();
|
||||||
|
Long storeId = cmd.getObjectStorageId();
|
||||||
|
String keyword = cmd.getKeyword();
|
||||||
|
Long startIndex = cmd.getStartIndex();
|
||||||
|
Long pageSize = cmd.getPageSizeVal();
|
||||||
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
|
List<Long> permittedAccounts = new ArrayList<Long>();
|
||||||
|
|
||||||
|
// Verify parameters
|
||||||
|
if (id != null) {
|
||||||
|
BucketVO bucket = bucketDao.findById(id);
|
||||||
|
if (bucket != null) {
|
||||||
|
accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, bucket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
|
||||||
|
|
||||||
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(),
|
||||||
|
cmd.isRecursive(), null);
|
||||||
|
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||||
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
|
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||||
|
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||||
|
|
||||||
|
Filter searchFilter = new Filter(BucketVO.class, "id", Boolean.TRUE, startIndex, pageSize);
|
||||||
|
|
||||||
|
SearchBuilder<BucketVO> sb = bucketDao.createSearchBuilder();
|
||||||
|
accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||||
|
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
|
||||||
|
// ids
|
||||||
|
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
||||||
|
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
|
|
||||||
|
SearchCriteria<BucketVO> sc = sb.create();
|
||||||
|
accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||||
|
|
||||||
|
if (keyword != null) {
|
||||||
|
SearchCriteria<BucketVO> ssc = bucketDao.createSearchCriteria();
|
||||||
|
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||||
|
ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||||
|
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
sc.setParameters("id", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name != null) {
|
||||||
|
sc.setParameters("name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIdsListToSearchCriteria(sc, ids);
|
||||||
|
|
||||||
|
// search Volume details by ids
|
||||||
|
Pair<List<BucketVO>, Integer> uniqueBktPair = bucketDao.searchAndCount(sc, searchFilter);
|
||||||
|
Integer count = uniqueBktPair.second();
|
||||||
|
if (count.intValue() == 0) {
|
||||||
|
// empty result
|
||||||
|
return uniqueBktPair.first();
|
||||||
|
}
|
||||||
|
List<BucketVO> uniqueBkts = uniqueBktPair.first();
|
||||||
|
Long[] bktIds = new Long[uniqueBkts.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (BucketVO b : uniqueBkts) {
|
||||||
|
bktIds[i++] = b.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return bucketDao.searchByIds(bktIds);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getConfigComponentName() {
|
public String getConfigComponentName() {
|
||||||
return QueryService.class.getSimpleName();
|
return QueryService.class.getSimpleName();
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -43,6 +44,7 @@ import org.apache.cloudstack.api.response.HostResponse;
|
|||||||
import org.apache.cloudstack.api.response.HostTagResponse;
|
import org.apache.cloudstack.api.response.HostTagResponse;
|
||||||
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.InstanceGroupResponse;
|
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.ProjectAccountResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||||
@ -58,6 +60,7 @@ import org.apache.cloudstack.api.response.UserVmResponse;
|
|||||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
@ -659,4 +662,20 @@ public class ViewResponseHelper {
|
|||||||
return new ArrayList<AffinityGroupResponse>(vrDataList.values());
|
return new ArrayList<AffinityGroupResponse>(vrDataList.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<ObjectStoreResponse> createObjectStoreResponse(ObjectStoreVO[] stores) {
|
||||||
|
Hashtable<Long, ObjectStoreResponse> storeList = new Hashtable<Long, ObjectStoreResponse>();
|
||||||
|
// Initialise the storeList with the input data
|
||||||
|
for (ObjectStoreVO store : stores) {
|
||||||
|
ObjectStoreResponse storeData = storeList.get(store.getId());
|
||||||
|
if (storeData == null) {
|
||||||
|
// first time encountering this store
|
||||||
|
storeData = ApiDBUtils.newObjectStoreResponse(store);
|
||||||
|
} else {
|
||||||
|
// update tags
|
||||||
|
storeData = ApiDBUtils.fillObjectStoreDetails(storeData, store);
|
||||||
|
}
|
||||||
|
storeList.put(store.getId(), storeData);
|
||||||
|
}
|
||||||
|
return new ArrayList<>(storeList.values());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,14 +209,17 @@ import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
|
|||||||
import org.apache.cloudstack.api.command.admin.snapshot.ListSnapshotsCmdByAdmin;
|
import org.apache.cloudstack.api.command.admin.snapshot.ListSnapshotsCmdByAdmin;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreS3CMD;
|
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreS3CMD;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.AddObjectStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.DeleteObjectStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.FindStoragePoolsForMigrationCmd;
|
import org.apache.cloudstack.api.command.admin.storage.FindStoragePoolsForMigrationCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.ListObjectStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
|
import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
|
||||||
@ -227,6 +230,7 @@ import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForM
|
|||||||
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateImageStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateImageStoreCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.UpdateObjectStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateStorageCapabilitiesCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateStorageCapabilitiesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
|
import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
|
||||||
@ -360,6 +364,10 @@ import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd
|
|||||||
import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd;
|
import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd;
|
||||||
import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd;
|
import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd;
|
||||||
import org.apache.cloudstack.api.command.user.autoscale.UpdateConditionCmd;
|
import org.apache.cloudstack.api.command.user.autoscale.UpdateConditionCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.CreateBucketCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.DeleteBucketCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.ListBucketsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.UpdateBucketCmd;
|
||||||
import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
|
import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
|
||||||
import org.apache.cloudstack.api.command.user.consoleproxy.CreateConsoleEndpointCmd;
|
import org.apache.cloudstack.api.command.user.consoleproxy.CreateConsoleEndpointCmd;
|
||||||
import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
|
import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
|
||||||
@ -3908,6 +3916,16 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
cmdList.add(DeleteUserDataCmd.class);
|
cmdList.add(DeleteUserDataCmd.class);
|
||||||
cmdList.add(ListUserDataCmd.class);
|
cmdList.add(ListUserDataCmd.class);
|
||||||
cmdList.add(LinkUserDataToTemplateCmd.class);
|
cmdList.add(LinkUserDataToTemplateCmd.class);
|
||||||
|
|
||||||
|
//object store APIs
|
||||||
|
cmdList.add(AddObjectStoragePoolCmd.class);
|
||||||
|
cmdList.add(ListObjectStoragePoolsCmd.class);
|
||||||
|
cmdList.add(UpdateObjectStoragePoolCmd.class);
|
||||||
|
cmdList.add(DeleteObjectStoragePoolCmd.class);
|
||||||
|
cmdList.add(CreateBucketCmd.class);
|
||||||
|
cmdList.add(UpdateBucketCmd.class);
|
||||||
|
cmdList.add(DeleteBucketCmd.class);
|
||||||
|
cmdList.add(ListBucketsCmd.class);
|
||||||
return cmdList;
|
return cmdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -54,9 +54,11 @@ import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaint
|
|||||||
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.DeleteObjectStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.UpdateObjectStoragePoolCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||||
@ -104,6 +106,9 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreObjectDownloadDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreObjectDownloadDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreObjectDownloadVO;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreObjectDownloadVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||||
@ -115,6 +120,8 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||||
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
|
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||||
|
import org.apache.cloudstack.storage.object.ObjectStoreEntity;
|
||||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang.time.DateUtils;
|
import org.apache.commons.lang.time.DateUtils;
|
||||||
@ -192,6 +199,7 @@ import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
|||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
import com.cloud.storage.Volume.Type;
|
import com.cloud.storage.Volume.Type;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
import com.cloud.storage.dao.DiskOfferingDao;
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import com.cloud.storage.dao.SnapshotDao;
|
import com.cloud.storage.dao.SnapshotDao;
|
||||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||||
@ -353,6 +361,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected UserVmManager userVmManager;
|
protected UserVmManager userVmManager;
|
||||||
|
@Inject
|
||||||
|
protected ObjectStoreDao _objectStoreDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected ObjectStoreDetailsDao _objectStoreDetailsDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected BucketDao _bucketDao;
|
||||||
protected List<StoragePoolDiscoverer> _discoverers;
|
protected List<StoragePoolDiscoverer> _discoverers;
|
||||||
|
|
||||||
public List<StoragePoolDiscoverer> getDiscoverers() {
|
public List<StoragePoolDiscoverer> getDiscoverers() {
|
||||||
@ -3633,4 +3649,124 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
volumeTO.setIopsWriteRate(getDiskIopsWriteRate(offering, diskOffering));
|
volumeTO.setIopsWriteRate(getDiskIopsWriteRate(offering, diskOffering));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_OBJECT_STORE_CREATE, eventDescription = "creating object storage")
|
||||||
|
public ObjectStore discoverObjectStore(String name, String url, String providerName, Map details)
|
||||||
|
throws IllegalArgumentException, InvalidParameterValueException {
|
||||||
|
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
||||||
|
|
||||||
|
if (storeProvider == null) {
|
||||||
|
throw new InvalidParameterValueException("can't find object store provider: " + providerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Unique object store name
|
||||||
|
ObjectStoreVO objectStore = _objectStoreDao.findByName(name);
|
||||||
|
if (objectStore != null) {
|
||||||
|
throw new InvalidParameterValueException("The object store with name " + name + " already exists, try creating with another name");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check URL
|
||||||
|
UriUtils.validateUrl(url);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new InvalidParameterValueException(url + " is not a valid URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Unique object store url
|
||||||
|
ObjectStoreVO objectStoreUrl = _objectStoreDao.findByUrl(url);
|
||||||
|
if (objectStoreUrl != null) {
|
||||||
|
throw new InvalidParameterValueException("The object store with url " + url + " already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("url", url);
|
||||||
|
params.put("name", name);
|
||||||
|
params.put("providerName", storeProvider.getName());
|
||||||
|
params.put("role", DataStoreRole.Object);
|
||||||
|
params.put("details", details);
|
||||||
|
|
||||||
|
DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
|
||||||
|
|
||||||
|
DataStore store;
|
||||||
|
try {
|
||||||
|
store = lifeCycle.initialize(params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Failed to add object store: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
throw new CloudRuntimeException("Failed to add object store: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ObjectStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_OBJECT_STORE_DELETE, eventDescription = "deleting object storage")
|
||||||
|
public boolean deleteObjectStore(DeleteObjectStoragePoolCmd cmd) {
|
||||||
|
final long storeId = cmd.getId();
|
||||||
|
// Verify that object store exists
|
||||||
|
ObjectStoreVO store = _objectStoreDao.findById(storeId);
|
||||||
|
if (store == null) {
|
||||||
|
throw new InvalidParameterValueException("Object store with id " + storeId + " doesn't exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that there are no buckets in the store
|
||||||
|
List<BucketVO> buckets = _bucketDao.listByObjectStoreId(storeId);
|
||||||
|
if(buckets != null && buckets.size() > 0) {
|
||||||
|
throw new InvalidParameterValueException("Cannot delete object store with buckets");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ready to delete
|
||||||
|
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||||
|
@Override
|
||||||
|
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||||
|
_objectStoreDetailsDao.deleteDetails(storeId);
|
||||||
|
_objectStoreDao.remove(storeId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
s_logger.debug("Successfully deleted object store with Id: "+storeId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_OBJECT_STORE_UPDATE, eventDescription = "update object storage")
|
||||||
|
public ObjectStore updateObjectStore(Long id, UpdateObjectStoragePoolCmd cmd) {
|
||||||
|
|
||||||
|
// Input validation
|
||||||
|
ObjectStoreVO objectStoreVO = _objectStoreDao.findById(id);
|
||||||
|
if (objectStoreVO == null) {
|
||||||
|
throw new IllegalArgumentException("Unable to find object store with ID: " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cmd.getUrl() != null ) {
|
||||||
|
String url = cmd.getUrl();
|
||||||
|
try {
|
||||||
|
// Check URL
|
||||||
|
UriUtils.validateUrl(url);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new InvalidParameterValueException(url + " is not a valid URL");
|
||||||
|
}
|
||||||
|
ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object);
|
||||||
|
String oldUrl = objectStoreVO.getUrl();
|
||||||
|
objectStoreVO.setUrl(url);
|
||||||
|
_objectStoreDao.update(id, objectStoreVO);
|
||||||
|
//Update URL and check access
|
||||||
|
try {
|
||||||
|
objectStore.listBuckets();
|
||||||
|
} catch (Exception e) {
|
||||||
|
//Revert to old URL on failure
|
||||||
|
objectStoreVO.setUrl(oldUrl);
|
||||||
|
_objectStoreDao.update(id, objectStoreVO);
|
||||||
|
throw new IllegalArgumentException("Unable to access Object Storage with URL: " + cmd.getUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cmd.getName() != null ) {
|
||||||
|
objectStoreVO.setName(cmd.getName());
|
||||||
|
}
|
||||||
|
_objectStoreDao.update(id, objectStoreVO);
|
||||||
|
s_logger.debug("Successfully updated object store with Id: "+id);
|
||||||
|
return objectStoreVO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -197,6 +197,7 @@ public final class AnnotationManagerImpl extends ManagerBase implements Annotati
|
|||||||
s_typeMap.put(EntityType.SYSTEM_VM, ApiCommandResourceType.SystemVm);
|
s_typeMap.put(EntityType.SYSTEM_VM, ApiCommandResourceType.SystemVm);
|
||||||
s_typeMap.put(EntityType.AUTOSCALE_VM_GROUP, ApiCommandResourceType.AutoScaleVmGroup);
|
s_typeMap.put(EntityType.AUTOSCALE_VM_GROUP, ApiCommandResourceType.AutoScaleVmGroup);
|
||||||
s_typeMap.put(EntityType.MANAGEMENT_SERVER, ApiCommandResourceType.Host);
|
s_typeMap.put(EntityType.MANAGEMENT_SERVER, ApiCommandResourceType.Host);
|
||||||
|
s_typeMap.put(EntityType.OBJECT_STORAGE, ApiCommandResourceType.ObjectStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KubernetesClusterHelper> getKubernetesClusterHelpers() {
|
public List<KubernetesClusterHelper> getKubernetesClusterHelpers() {
|
||||||
|
|||||||
@ -0,0 +1,304 @@
|
|||||||
|
// 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.object;
|
||||||
|
|
||||||
|
import com.amazonaws.services.s3.internal.BucketNameUtils;
|
||||||
|
import com.amazonaws.services.s3.model.IllegalBucketNameException;
|
||||||
|
import com.cloud.event.ActionEvent;
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.storage.DataStoreRole;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
|
import com.cloud.usage.BucketStatisticsVO;
|
||||||
|
import com.cloud.usage.dao.BucketStatisticsDao;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.user.AccountManager;
|
||||||
|
import com.cloud.utils.component.ManagerBase;
|
||||||
|
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||||
|
import com.cloud.utils.db.GlobalLock;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.CreateBucketCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.UpdateBucketCmd;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
|
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.naming.ConfigurationException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class BucketApiServiceImpl extends ManagerBase implements BucketApiService, Configurable {
|
||||||
|
private final static Logger s_logger = Logger.getLogger(BucketApiServiceImpl.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ObjectStoreDao _objectStoreDao;
|
||||||
|
@Inject
|
||||||
|
DataStoreManager _dataStoreMgr;
|
||||||
|
@Inject
|
||||||
|
private BucketDao _bucketDao;
|
||||||
|
@Inject
|
||||||
|
private AccountManager _accountMgr;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BucketStatisticsDao _bucketStatisticsDao;
|
||||||
|
|
||||||
|
private ScheduledExecutorService _executor = null;
|
||||||
|
|
||||||
|
private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3;
|
||||||
|
|
||||||
|
protected BucketApiServiceImpl() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
|
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Bucket-Usage"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean start() {
|
||||||
|
_executor.scheduleWithFixedDelay(new BucketUsageTask(), 60L, 3600L, TimeUnit.SECONDS);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean stop() {
|
||||||
|
_executor.shutdown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConfigComponentName() {
|
||||||
|
return BucketApiService.class.getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
|
return new ConfigKey<?>[] {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_BUCKET_CREATE, eventDescription = "creating bucket", create = true)
|
||||||
|
public Bucket allocBucket(CreateBucketCmd cmd) {
|
||||||
|
try {
|
||||||
|
BucketNameUtils.validateBucketName(cmd.getBucketName());
|
||||||
|
} catch (IllegalBucketNameException e) {
|
||||||
|
s_logger.error("Invalid Bucket Name: " +cmd.getBucketName(), e);
|
||||||
|
throw new InvalidParameterValueException("Invalid Bucket Name: "+e.getMessage());
|
||||||
|
}
|
||||||
|
//ToDo check bucket exists
|
||||||
|
long ownerId = cmd.getEntityOwnerId();
|
||||||
|
Account owner = _accountMgr.getActiveAccountById(ownerId);
|
||||||
|
ObjectStoreVO objectStoreVO = _objectStoreDao.findById(cmd.getObjectStoragePoolId());
|
||||||
|
ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object);
|
||||||
|
try {
|
||||||
|
if(!objectStore.createUser(ownerId)) {
|
||||||
|
s_logger.error("Failed to create user in objectstore "+ objectStore.getName());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (CloudRuntimeException e) {
|
||||||
|
s_logger.error("Error while checking object store user.", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BucketVO bucket = new BucketVO(ownerId, owner.getDomainId(), cmd.getObjectStoragePoolId(), cmd.getBucketName(), cmd.getQuota(),
|
||||||
|
cmd.isVersioning(), cmd.isEncryption(), cmd.isObjectLocking(), cmd.getPolicy());
|
||||||
|
_bucketDao.persist(bucket);
|
||||||
|
return bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_BUCKET_CREATE, eventDescription = "creating bucket", async = true)
|
||||||
|
public Bucket createBucket(CreateBucketCmd cmd) {
|
||||||
|
ObjectStoreVO objectStoreVO = _objectStoreDao.findById(cmd.getObjectStoragePoolId());
|
||||||
|
ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object);
|
||||||
|
BucketVO bucket = _bucketDao.findById(cmd.getEntityId());
|
||||||
|
boolean objectLock = false;
|
||||||
|
boolean bucketCreated = false;
|
||||||
|
if(cmd.isObjectLocking()) {
|
||||||
|
objectLock = true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
objectStore.createBucket(bucket, objectLock);
|
||||||
|
bucketCreated = true;
|
||||||
|
|
||||||
|
if (cmd.isVersioning()) {
|
||||||
|
objectStore.setBucketVersioning(bucket.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.isEncryption()) {
|
||||||
|
objectStore.setBucketEncryption(bucket.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.getQuota() != null) {
|
||||||
|
objectStore.setQuota(bucket.getName(), cmd.getQuota());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.getPolicy() != null) {
|
||||||
|
objectStore.setBucketPolicy(bucket.getName(), cmd.getPolicy());
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket.setState(Bucket.State.Created);
|
||||||
|
_bucketDao.update(bucket.getId(), bucket);
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.debug("Failed to create bucket with name: "+bucket.getName(), e);
|
||||||
|
if(bucketCreated) {
|
||||||
|
objectStore.deleteBucket(bucket.getName());
|
||||||
|
}
|
||||||
|
_bucketDao.remove(bucket.getId());
|
||||||
|
throw new CloudRuntimeException("Failed to create bucket with name: "+bucket.getName()+". "+e.getMessage());
|
||||||
|
}
|
||||||
|
return bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_BUCKET_DELETE, eventDescription = "deleting bucket")
|
||||||
|
public boolean deleteBucket(long bucketId, Account caller) {
|
||||||
|
Bucket bucket = _bucketDao.findById(bucketId);
|
||||||
|
if (bucket == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find bucket with ID: " + bucketId);
|
||||||
|
}
|
||||||
|
_accountMgr.checkAccess(caller, null, true, bucket);
|
||||||
|
ObjectStoreVO objectStoreVO = _objectStoreDao.findById(bucket.getObjectStoreId());
|
||||||
|
ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object);
|
||||||
|
if (objectStore.deleteBucket(bucket.getName())) {
|
||||||
|
return _bucketDao.remove(bucketId);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_BUCKET_UPDATE, eventDescription = "updating bucket")
|
||||||
|
public boolean updateBucket(UpdateBucketCmd cmd, Account caller) {
|
||||||
|
BucketVO bucket = _bucketDao.findById(cmd.getId());
|
||||||
|
if (bucket == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find bucket with ID: " + cmd.getId());
|
||||||
|
}
|
||||||
|
_accountMgr.checkAccess(caller, null, true, bucket);
|
||||||
|
ObjectStoreVO objectStoreVO = _objectStoreDao.findById(bucket.getObjectStoreId());
|
||||||
|
ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object);
|
||||||
|
try {
|
||||||
|
if (cmd.getEncryption() != null) {
|
||||||
|
if (cmd.getEncryption()) {
|
||||||
|
objectStore.setBucketEncryption(bucket.getName());
|
||||||
|
} else {
|
||||||
|
objectStore.deleteBucketEncryption(bucket.getName());
|
||||||
|
}
|
||||||
|
bucket.setEncryption(cmd.getEncryption());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.getVersioning() != null) {
|
||||||
|
if (cmd.getVersioning()) {
|
||||||
|
objectStore.setBucketVersioning(bucket.getName());
|
||||||
|
} else {
|
||||||
|
objectStore.deleteBucketVersioning(bucket.getName());
|
||||||
|
}
|
||||||
|
bucket.setVersioning(cmd.getVersioning());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.getPolicy() != null) {
|
||||||
|
objectStore.setBucketPolicy(bucket.getName(), cmd.getPolicy());
|
||||||
|
bucket.setPolicy(cmd.getPolicy());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.getQuota() != null) {
|
||||||
|
objectStore.setQuota(bucket.getName(), cmd.getQuota());
|
||||||
|
bucket.setQuota(cmd.getQuota());
|
||||||
|
}
|
||||||
|
_bucketDao.update(bucket.getId(), bucket);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException("Error while updating bucket: " +bucket.getName() +". "+e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getBucketUsage() {
|
||||||
|
//ToDo track usage one last time when object store or bucket is removed
|
||||||
|
List<ObjectStoreVO> objectStores = _objectStoreDao.listObjectStores();
|
||||||
|
for(ObjectStoreVO objectStoreVO: objectStores) {
|
||||||
|
ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object);
|
||||||
|
Map<String, Long> bucketSizes = objectStore.getAllBucketsUsage();
|
||||||
|
List<BucketVO> buckets = _bucketDao.listByObjectStoreId(objectStoreVO.getId());
|
||||||
|
for(BucketVO bucket : buckets) {
|
||||||
|
Long size = bucketSizes.get(bucket.getName());
|
||||||
|
if( size != null){
|
||||||
|
bucket.setSize(size);
|
||||||
|
_bucketDao.update(bucket.getId(), bucket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BucketUsageTask extends ManagedContextRunnable {
|
||||||
|
public BucketUsageTask() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void runInContext() {
|
||||||
|
GlobalLock scanLock = GlobalLock.getInternLock("BucketUsage");
|
||||||
|
try {
|
||||||
|
if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
|
||||||
|
try {
|
||||||
|
List<ObjectStoreVO> objectStores = _objectStoreDao.listObjectStores();
|
||||||
|
for(ObjectStoreVO objectStoreVO: objectStores) {
|
||||||
|
ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object);
|
||||||
|
Map<String, Long> bucketSizes = objectStore.getAllBucketsUsage();
|
||||||
|
List<BucketVO> buckets = _bucketDao.listByObjectStoreId(objectStoreVO.getId());
|
||||||
|
for(BucketVO bucket : buckets) {
|
||||||
|
Long size = bucketSizes.get(bucket.getName());
|
||||||
|
if( size != null){
|
||||||
|
bucket.setSize(size);
|
||||||
|
_bucketDao.update(bucket.getId(), bucket);
|
||||||
|
|
||||||
|
//Update Bucket Usage stats
|
||||||
|
BucketStatisticsVO bucketStatisticsVO = _bucketStatisticsDao.findBy(bucket.getAccountId(), bucket.getId());
|
||||||
|
if(bucketStatisticsVO != null) {
|
||||||
|
bucketStatisticsVO.setSize(size);
|
||||||
|
_bucketStatisticsDao.update(bucketStatisticsVO.getId(), bucketStatisticsVO);
|
||||||
|
} else {
|
||||||
|
bucketStatisticsVO = new BucketStatisticsVO(bucket.getAccountId(), bucket.getId());
|
||||||
|
bucketStatisticsVO.setSize(size);
|
||||||
|
_bucketStatisticsDao.persist(bucketStatisticsVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_logger.debug("Completed updating bucket usage for all object stores");
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.error("Error while fetching bucket usage", e);
|
||||||
|
} finally {
|
||||||
|
scanLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
scanLock.releaseRef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -352,6 +352,7 @@
|
|||||||
class="com.cloud.tags.ResourceManagerUtilImpl"/>
|
class="com.cloud.tags.ResourceManagerUtilImpl"/>
|
||||||
|
|
||||||
<bean id="resourceIconManager" class="com.cloud.resourceicon.ResourceIconManagerImpl" />
|
<bean id="resourceIconManager" class="com.cloud.resourceicon.ResourceIconManagerImpl" />
|
||||||
|
<bean id="bucketApiServiceImpl" class="org.apache.cloudstack.storage.object.BucketApiServiceImpl" />
|
||||||
|
|
||||||
<bean id="VMScheduleManagerImpl" class="org.apache.cloudstack.vm.schedule.VMScheduleManagerImpl" />
|
<bean id="VMScheduleManagerImpl" class="org.apache.cloudstack.vm.schedule.VMScheduleManagerImpl" />
|
||||||
<bean id="VMSchedulerImpl" class="org.apache.cloudstack.vm.schedule.VMSchedulerImpl">
|
<bean id="VMSchedulerImpl" class="org.apache.cloudstack.vm.schedule.VMSchedulerImpl">
|
||||||
|
|||||||
@ -27,6 +27,8 @@ import com.cloud.network.Network;
|
|||||||
import com.cloud.network.VNF;
|
import com.cloud.network.VNF;
|
||||||
import com.cloud.network.dao.NetworkVO;
|
import com.cloud.network.dao.NetworkVO;
|
||||||
import com.cloud.server.ResourceTag;
|
import com.cloud.server.ResourceTag;
|
||||||
|
import com.cloud.storage.BucketVO;
|
||||||
|
import com.cloud.storage.dao.BucketDao;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
@ -40,12 +42,17 @@ import com.cloud.utils.db.SearchCriteria;
|
|||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||||
|
import org.apache.cloudstack.api.command.admin.storage.ListObjectStoragePoolsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.bucket.ListBucketsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
||||||
import org.apache.cloudstack.api.command.user.resource.ListDetailOptionsCmd;
|
import org.apache.cloudstack.api.command.user.resource.ListDetailOptionsCmd;
|
||||||
import org.apache.cloudstack.api.response.DetailOptionsResponse;
|
import org.apache.cloudstack.api.response.DetailOptionsResponse;
|
||||||
import org.apache.cloudstack.api.response.EventResponse;
|
import org.apache.cloudstack.api.response.EventResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -66,6 +73,8 @@ import java.util.Set;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
@ -95,6 +104,12 @@ public class QueryManagerImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
SearchCriteria searchCriteriaMock;
|
SearchCriteria searchCriteriaMock;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObjectStoreDao objectStoreDao;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
BucketDao bucketDao;
|
||||||
|
|
||||||
private AccountVO account;
|
private AccountVO account;
|
||||||
private UserVO user;
|
private UserVO user;
|
||||||
|
|
||||||
@ -288,4 +303,41 @@ public class QueryManagerImplTest {
|
|||||||
|
|
||||||
Assert.assertTrue(set.contains(domainId));
|
Assert.assertTrue(set.contains(domainId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchForObjectStores() {
|
||||||
|
ListObjectStoragePoolsCmd cmd = new ListObjectStoragePoolsCmd();
|
||||||
|
List<ObjectStoreVO> objectStores = new ArrayList<>();
|
||||||
|
ObjectStoreVO os1 = new ObjectStoreVO();
|
||||||
|
os1.setName("MinIOStore");
|
||||||
|
ObjectStoreVO os2 = new ObjectStoreVO();
|
||||||
|
os1.setName("Simulator");
|
||||||
|
objectStores.add(os1);
|
||||||
|
objectStores.add(os2);
|
||||||
|
SearchBuilder<ObjectStoreVO> sb = Mockito.mock(SearchBuilder.class);
|
||||||
|
ObjectStoreVO objectStoreVO = Mockito.mock(ObjectStoreVO.class);
|
||||||
|
when(sb.entity()).thenReturn(objectStoreVO);
|
||||||
|
when(objectStoreDao.createSearchBuilder()).thenReturn(sb);
|
||||||
|
when(objectStoreDao.searchAndCount(any(), any())).thenReturn(new Pair<>(objectStores, 2));
|
||||||
|
ListResponse<ObjectStoreResponse> result = queryManagerImplSpy.searchForObjectStores(cmd);
|
||||||
|
assertEquals(2, result.getCount().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchForBuckets() {
|
||||||
|
ListBucketsCmd listBucketsCmd = new ListBucketsCmd();
|
||||||
|
List<BucketVO> buckets = new ArrayList<>();
|
||||||
|
BucketVO b1 = new BucketVO();
|
||||||
|
b1.setName("test-bucket-1");
|
||||||
|
BucketVO b2 = new BucketVO();
|
||||||
|
b2.setName("test-bucket-1");
|
||||||
|
buckets.add(b1);
|
||||||
|
buckets.add(b2);
|
||||||
|
SearchBuilder<BucketVO> sb = Mockito.mock(SearchBuilder.class);
|
||||||
|
BucketVO bucketVO = Mockito.mock(BucketVO.class);
|
||||||
|
when(sb.entity()).thenReturn(bucketVO);
|
||||||
|
when(bucketDao.createSearchBuilder()).thenReturn(sb);
|
||||||
|
when(bucketDao.searchAndCount(any(), any())).thenReturn(new Pair<>(buckets, 2));
|
||||||
|
queryManagerImplSpy.searchForBuckets(listBucketsCmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
111
test/integration/smoke/test_bucket.py
Normal file
111
test/integration/smoke/test_bucket.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# 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.
|
||||||
|
""" BVT tests for Bucket Operations"""
|
||||||
|
|
||||||
|
#Import Local Modules
|
||||||
|
from marvin.cloudstackTestCase import *
|
||||||
|
from nose.plugins.attrib import attr
|
||||||
|
from marvin.lib.base import (ObjectStoragePool, Bucket)
|
||||||
|
from marvin.lib.utils import (cleanup_resources)
|
||||||
|
|
||||||
|
_multiprocess_shared_ = True
|
||||||
|
|
||||||
|
class TestObjectStore(cloudstackTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.services = self.testClient.getParsedTestDataConfig()
|
||||||
|
self.apiclient = self.testClient.getApiClient()
|
||||||
|
self.dbclient = self.testClient.getDbConnection()
|
||||||
|
self.cleanup = []
|
||||||
|
return
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
try:
|
||||||
|
#Clean up, terminate the created resources
|
||||||
|
cleanup_resources(self.apiclient, self.cleanup)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||||
|
return
|
||||||
|
|
||||||
|
@attr(tags=["smoke"], required_hardware="false")
|
||||||
|
def test_01_create_bucket(self):
|
||||||
|
"""Test to create bucket in object store
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
object_store = ObjectStoragePool.create(
|
||||||
|
self.apiclient,
|
||||||
|
"testOS-9",
|
||||||
|
"http://192.168.0.1",
|
||||||
|
"Simulator",
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
|
self.debug("Created Object Store with ID: %s" % object_store.id)
|
||||||
|
|
||||||
|
bucket = Bucket.create(
|
||||||
|
self.apiclient,
|
||||||
|
"mybucket",
|
||||||
|
object_store.id
|
||||||
|
)
|
||||||
|
|
||||||
|
list_buckets_response = Bucket.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=bucket.id
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertNotEqual(
|
||||||
|
len(list_buckets_response),
|
||||||
|
0,
|
||||||
|
"Check List Bucket response"
|
||||||
|
)
|
||||||
|
|
||||||
|
bucket_response = list_buckets_response[0]
|
||||||
|
self.assertEqual(
|
||||||
|
object_store.id,
|
||||||
|
bucket_response.objectstorageid,
|
||||||
|
"Check object store id of the created Bucket"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
"mybucket",
|
||||||
|
bucket_response.name,
|
||||||
|
"Check Name of the created Bucket"
|
||||||
|
)
|
||||||
|
|
||||||
|
bucket.update(
|
||||||
|
self.apiclient,
|
||||||
|
quota=100
|
||||||
|
)
|
||||||
|
|
||||||
|
list_buckets_response_updated = Bucket.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=bucket.id
|
||||||
|
)
|
||||||
|
|
||||||
|
bucket_response_updated = list_buckets_response_updated[0]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
100,
|
||||||
|
bucket_response_updated.quota,
|
||||||
|
"Check quota of the updated bucket"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.cleanup.append(bucket)
|
||||||
|
self.cleanup.append(object_store)
|
||||||
|
|
||||||
|
return
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user