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_adapter_type
|
||||
smoke/test_non_contigiousvlan
|
||||
smoke/test_object_stores
|
||||
smoke/test_outofbandmanagement
|
||||
smoke/test_outofbandmanagement_nestedplugin
|
||||
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.config.Configuration;
|
||||
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.vm.schedule.VMSchedule;
|
||||
|
||||
@ -714,6 +716,16 @@ public class EventTypes {
|
||||
// SystemVM
|
||||
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 {
|
||||
|
||||
// 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_OBJECT_DOWNLOAD, ImageStore.class);
|
||||
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) {
|
||||
|
||||
@ -69,7 +69,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
||||
GuestOs(false, true),
|
||||
NetworkOffering(false, true),
|
||||
VpcOffering(true, false),
|
||||
Domain(false, false, true);
|
||||
Domain(false, false, true),
|
||||
ObjectStore(false, false, true);
|
||||
|
||||
|
||||
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) {
|
||||
|
||||
@ -21,7 +21,7 @@ package com.cloud.storage;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
public enum DataStoreRole {
|
||||
Primary("primary"), Image("image"), ImageCache("imagecache"), Backup("backup");
|
||||
Primary("primary"), Image("image"), ImageCache("imagecache"), Backup("backup"), Object("object");
|
||||
|
||||
public boolean isImageStore() {
|
||||
return (role.equalsIgnoreCase("image") || role.equalsIgnoreCase("imagecache")) ? true : false;
|
||||
@ -45,6 +45,8 @@ public enum DataStoreRole {
|
||||
return ImageCache;
|
||||
} else if (role.equalsIgnoreCase("backup")) {
|
||||
return Backup;
|
||||
} else if (role.equalsIgnoreCase("object")) {
|
||||
return Object;
|
||||
} else {
|
||||
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.CreateStoragePoolCmd;
|
||||
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.DeleteSecondaryStagingStoreCmd;
|
||||
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 com.cloud.exception.DiscoveryException;
|
||||
@ -34,6 +36,7 @@ import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||
|
||||
public interface StorageService {
|
||||
/**
|
||||
@ -109,4 +112,9 @@ public interface StorageService {
|
||||
|
||||
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),
|
||||
ZONE(false), POD(false), CLUSTER(false), HOST(false), DOMAIN(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;
|
||||
|
||||
@ -78,6 +78,7 @@ public interface AnnotationService {
|
||||
list.add(EntityType.VR);
|
||||
list.add(EntityType.SYSTEM_VM);
|
||||
list.add(EntityType.MANAGEMENT_SERVER);
|
||||
list.add(EntityType.OBJECT_STORAGE);
|
||||
if (roleType != RoleType.DomainAdmin) {
|
||||
list.add(EntityType.DOMAIN);
|
||||
list.add(EntityType.SERVICE_OFFERING);
|
||||
|
||||
@ -78,7 +78,9 @@ public enum ApiCommandResourceType {
|
||||
VmSnapshot(com.cloud.vm.snapshot.VMSnapshot.class),
|
||||
Role(org.apache.cloudstack.acl.Role.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;
|
||||
|
||||
|
||||
@ -1049,10 +1049,17 @@ public class ApiConstants {
|
||||
public static final String MTU = "mtu";
|
||||
public static final String AUTO_ENABLE_KVM_HOST = "autoenablekvmhost";
|
||||
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_ID = "sourcenatipaddressid";
|
||||
public static final String HAS_RULES = "hasrules";
|
||||
public static final String OBJECT_STORAGE = "objectstore";
|
||||
|
||||
public static final String MANAGEMENT = "management";
|
||||
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.InternalLoadBalancerVMService;
|
||||
import org.apache.cloudstack.query.QueryService;
|
||||
import org.apache.cloudstack.storage.object.BucketApiService;
|
||||
import org.apache.cloudstack.storage.ImageStoreService;
|
||||
import org.apache.cloudstack.storage.template.VnfTemplateManager;
|
||||
import org.apache.cloudstack.usage.UsageService;
|
||||
@ -216,6 +217,9 @@ public abstract class BaseCmd {
|
||||
public Ipv6Service ipv6Service;
|
||||
@Inject
|
||||
public VnfTemplateManager vnfTemplateManager;
|
||||
@Inject
|
||||
public BucketApiService _bucketService;
|
||||
|
||||
|
||||
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||
ResourceAllocationException, NetworkRuleConflictException;
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.cloudstack.storage.object.Bucket;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
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.BackupResponse;
|
||||
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.ClusterResponse;
|
||||
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.NicResponse;
|
||||
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.PhysicalNetworkResponse;
|
||||
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.PortableIpRange;
|
||||
import org.apache.cloudstack.region.Region;
|
||||
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||
import org.apache.cloudstack.usage.Usage;
|
||||
|
||||
import com.cloud.capacity.Capacity;
|
||||
@ -533,4 +537,8 @@ public interface ResponseGenerator {
|
||||
FirewallResponse createIpv6FirewallRuleResponse(FirewallRule acl);
|
||||
|
||||
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.ListRoutersCmd;
|
||||
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.ListStoragePoolsCmd;
|
||||
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.address.ListQuarantinedIpsCmd;
|
||||
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.iso.ListIsosCmd;
|
||||
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.response.AccountResponse;
|
||||
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.DiskOfferingResponse;
|
||||
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.ListResponse;
|
||||
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.ProjectInvitationResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
@ -190,4 +194,8 @@ public interface QueryService {
|
||||
ListResponse<SnapshotResponse> listSnapshots(ListSnapshotsCmd 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 VM_SNAPSHOT_ON_PRIMARY = 27;
|
||||
public static final int BACKUP = 28;
|
||||
public static final int BUCKET = 29;
|
||||
|
||||
public static List<UsageTypeResponse> listUsageTypes() {
|
||||
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(VM_SNAPSHOT_ON_PRIMARY, "VM Snapshot on primary storage usage"));
|
||||
responseList.add(new UsageTypeResponse(BACKUP, "Backup storage usage"));
|
||||
responseList.add(new UsageTypeResponse(BUCKET, "Bucket storage usage"));
|
||||
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>
|
||||
<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-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>
|
||||
<build>
|
||||
<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";
|
||||
|
||||
enum DataStoreProviderType {
|
||||
PRIMARY, IMAGE, ImageCache
|
||||
PRIMARY, IMAGE, ImageCache, OBJECT
|
||||
}
|
||||
|
||||
DataStoreLifeCycle getDataStoreLifeCycle();
|
||||
|
||||
@ -33,4 +33,6 @@ public interface DataStoreProviderManager extends Manager, DataStoreProviderApiS
|
||||
DataStoreProvider getDefaultCacheDataStoreProvider();
|
||||
|
||||
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/datamotion</module>
|
||||
<module>storage/image</module>
|
||||
<module>storage/object</module>
|
||||
<module>storage/snapshot</module>
|
||||
<module>storage/volume</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.
|
||||
package com.cloud.usage.dao;
|
||||
|
||||
import com.cloud.usage.BucketStatisticsVO;
|
||||
import com.cloud.usage.UsageVO;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.UserStatisticsVO;
|
||||
@ -45,6 +46,12 @@ public interface UsageDao extends GenericDao<UsageVO, Long> {
|
||||
|
||||
Long getLastUserStatsId();
|
||||
|
||||
Long getLastBucketStatsId();
|
||||
|
||||
void saveBucketStats(List<BucketStatisticsVO> userStats);
|
||||
|
||||
void updateBucketStats(List<BucketStatisticsVO> userStats);
|
||||
|
||||
List<Long> listPublicTemplatesByAccount(long accountId);
|
||||
|
||||
Long getLastVmDiskStatsId();
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
// under the License.
|
||||
package com.cloud.usage.dao;
|
||||
|
||||
import com.cloud.usage.BucketStatisticsVO;
|
||||
import com.cloud.usage.UsageVO;
|
||||
import com.cloud.user.AccountVO;
|
||||
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 <= ? "
|
||||
+ "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() {
|
||||
}
|
||||
|
||||
@ -285,6 +293,69 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
||||
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
|
||||
public List<Long> listPublicTemplatesByAccount(long accountId) {
|
||||
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="ClusterDrsPlanDaoImpl" class="org.apache.cloudstack.cluster.dao.ClusterDrsPlanDaoImpl" />
|
||||
<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>
|
||||
|
||||
@ -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` 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="vmsnapshotDetailsDao" class="com.cloud.vm.snapshot.dao.VMSnapshotDetailsDaoImpl" />
|
||||
<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>
|
||||
|
||||
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.ZoneScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
||||
import org.apache.cloudstack.storage.object.datastore.ObjectStoreProviderManager;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
||||
@ -40,6 +41,8 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
||||
PrimaryDataStoreProviderManager primaryStoreMgr;
|
||||
@Inject
|
||||
ImageStoreProviderManager imageDataStoreMgr;
|
||||
@Inject
|
||||
ObjectStoreProviderManager objectStoreProviderMgr;
|
||||
|
||||
@Override
|
||||
public DataStore getDataStore(long storeId, DataStoreRole role) {
|
||||
@ -50,6 +53,8 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
||||
return imageDataStoreMgr.getImageStore(storeId);
|
||||
} else if (role == DataStoreRole.ImageCache) {
|
||||
return imageDataStoreMgr.getImageStore(storeId);
|
||||
} else if (role == DataStoreRole.Object) {
|
||||
return objectStoreProviderMgr.getObjectStore(storeId);
|
||||
}
|
||||
} catch (CloudRuntimeException e) {
|
||||
throw e;
|
||||
@ -63,6 +68,8 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
||||
return primaryStoreMgr.getPrimaryDataStore(uuid);
|
||||
} else if (role == DataStoreRole.Image) {
|
||||
return imageDataStoreMgr.getImageStore(uuid);
|
||||
} else if (role == DataStoreRole.Object) {
|
||||
return objectStoreProviderMgr.getObjectStore(uuid);
|
||||
}
|
||||
throw new CloudRuntimeException("un recognized type" + role);
|
||||
}
|
||||
|
||||
@ -30,6 +30,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import javax.inject.Inject;
|
||||
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.springframework.stereotype.Component;
|
||||
|
||||
@ -56,6 +58,8 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
||||
PrimaryDataStoreProviderManager primaryDataStoreProviderMgr;
|
||||
@Inject
|
||||
ImageStoreProviderManager imageStoreProviderMgr;
|
||||
@Inject
|
||||
ObjectStoreProviderManager objectStoreProviderMgr;
|
||||
|
||||
@Override
|
||||
public DataStoreProvider getDataStoreProvider(String name) {
|
||||
@ -144,6 +148,8 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
||||
primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener());
|
||||
} else if (types.contains(DataStoreProviderType.IMAGE)) {
|
||||
imageStoreProviderMgr.registerDriver(provider.getName(), (ImageStoreDriver)provider.getDataStoreDriver());
|
||||
} else if (types.contains(DataStoreProviderType.OBJECT)) {
|
||||
objectStoreProviderMgr.registerDriver(provider.getName(), (ObjectStoreDriver)provider.getDataStoreDriver());
|
||||
}
|
||||
} catch (Exception 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreProvider getDefaultObjectStoreProvider() {
|
||||
return this.getDataStoreProvider(DataStoreProvider.S3_IMAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageProviderResponse> getDataStoreProviders(String type) {
|
||||
if (type == null) {
|
||||
@ -180,7 +191,9 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
||||
return this.getImageDataStoreProviders();
|
||||
} else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.ImageCache.toString())) {
|
||||
return this.getCacheDataStoreProviders();
|
||||
} else {
|
||||
} else if (type.equalsIgnoreCase(DataStoreProviderType.OBJECT.toString())) {
|
||||
return this.getObjectStoreProviders();
|
||||
}else {
|
||||
throw new InvalidParameterValueException("Invalid parameter: " + type);
|
||||
}
|
||||
}
|
||||
@ -223,4 +236,16 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
|
||||
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(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(BUCKET, new QuotaTypes(BUCKET, "BUCKET", UsageUnitTypes.GB_MONTH.toString(), "Object Store bucket usage"));
|
||||
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.ZoneMetricsResponse;
|
||||
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.utils.bytescale.ByteScaleUtils;
|
||||
import org.apache.commons.beanutils.BeanUtils;
|
||||
@ -176,6 +177,9 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
||||
@Inject
|
||||
private VolumeStatsDao volumeStatsDao;
|
||||
|
||||
@Inject
|
||||
private ObjectStoreDao objectStoreDao;
|
||||
|
||||
private static Gson gson = new Gson();
|
||||
|
||||
protected MetricsServiceImpl() {
|
||||
@ -557,6 +561,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
||||
response.setHosts(hostDao.countAllByType(Host.Type.Routing));
|
||||
response.setStoragePools(storagePoolDao.countAll());
|
||||
response.setImageStores(imageStoreDao.countAllImageStores());
|
||||
response.setObjectStores(objectStoreDao.countAllObjectStores());
|
||||
response.setSystemvms(vmInstanceDao.listByTypes(VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm).size());
|
||||
response.setRouters(domainRouterDao.countAllByRole(VirtualRouter.Role.VIRTUAL_ROUTER));
|
||||
response.setInternalLbs(domainRouterDao.countAllByRole(VirtualRouter.Role.INTERNAL_LB_VM));
|
||||
|
||||
@ -47,6 +47,10 @@ public class InfrastructureResponse extends BaseResponse {
|
||||
@Param(description = "Number of images stores")
|
||||
private Integer imageStores;
|
||||
|
||||
@SerializedName("objectstores")
|
||||
@Param(description = "Number of object stores")
|
||||
private Integer objectStores;
|
||||
|
||||
@SerializedName("systemvms")
|
||||
@Param(description = "Number of systemvms")
|
||||
private Integer systemvms;
|
||||
@ -118,4 +122,8 @@ public class InfrastructureResponse extends BaseResponse {
|
||||
public void setAlerts(Integer alerts) { this.alerts = alerts; }
|
||||
|
||||
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/linstor</module>
|
||||
<module>storage/volume/storpool</module>
|
||||
<module>storage/object/minio</module>
|
||||
<module>storage/object/simulator</module>
|
||||
|
||||
|
||||
<module>storage-allocators/random</module>
|
||||
@ -187,6 +189,30 @@
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</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>
|
||||
<profiles>
|
||||
<profile>
|
||||
|
||||
@ -18,12 +18,15 @@
|
||||
package org.apache.cloudstack.shutdown;
|
||||
|
||||
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@ -39,6 +42,12 @@ public class ShutdownManagerImplTest {
|
||||
|
||||
@Mock
|
||||
AsyncJobManager jobManagerMock;
|
||||
private AutoCloseable closeable;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
closeable = MockitoAnnotations.openMocks(this);
|
||||
}
|
||||
|
||||
private long prepareCountPendingJobs() {
|
||||
long expectedCount = 1L;
|
||||
@ -75,4 +84,9 @@ public class ShutdownManagerImplTest {
|
||||
spy.cancelShutdown();
|
||||
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.VolumeStats;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.BucketDao;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||
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.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 {
|
||||
private static ManagementServer s_ms;
|
||||
static AsyncJobManager s_asyncMgr;
|
||||
@ -481,6 +486,9 @@ public class ApiDBUtils {
|
||||
static NicDao s_nicDao;
|
||||
static ResourceManagerUtil s_resourceManagerUtil;
|
||||
static SnapshotPolicyDetailsDao s_snapshotPolicyDetailsDao;
|
||||
static ObjectStoreDao s_objectStoreDao;
|
||||
|
||||
static BucketDao s_bucketDao;
|
||||
|
||||
@Inject
|
||||
private ManagementServer ms;
|
||||
@ -740,6 +748,11 @@ public class ApiDBUtils {
|
||||
@Inject
|
||||
SnapshotPolicyDetailsDao snapshotPolicyDetailsDao;
|
||||
|
||||
@Inject
|
||||
private ObjectStoreDao objectStoreDao;
|
||||
@Inject
|
||||
private BucketDao bucketDao;
|
||||
|
||||
@PostConstruct
|
||||
void init() {
|
||||
s_ms = ms;
|
||||
@ -871,6 +884,8 @@ public class ApiDBUtils {
|
||||
s_backupOfferingDao = backupOfferingDao;
|
||||
s_resourceIconDao = resourceIconDao;
|
||||
s_resourceManagerUtil = resourceManagerUtil;
|
||||
s_objectStoreDao = objectStoreDao;
|
||||
s_bucketDao = bucketDao;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////
|
||||
@ -2208,4 +2223,12 @@ public class ApiDBUtils {
|
||||
public static NicSecondaryIpVO findSecondaryIpByIp4AddressAndNetworkId(String ip4Address, long 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 com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.BucketVO;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
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.BackupResponse;
|
||||
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.CapacityResponse;
|
||||
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.NicResponse;
|
||||
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.PhysicalNetworkResponse;
|
||||
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.PortableIpRange;
|
||||
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.SnapshotDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||
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.UsageService;
|
||||
import org.apache.cloudstack.usage.UsageTypes;
|
||||
@ -263,7 +271,6 @@ import com.cloud.gpu.GPU;
|
||||
import com.cloud.host.ControlState;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.HypervisorCapabilities;
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
@ -470,6 +477,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
@Inject
|
||||
UserDataDao userDataDao;
|
||||
|
||||
@Inject
|
||||
ObjectStoreDao _objectStoreDao;
|
||||
|
||||
@Override
|
||||
public UserResponse createUserResponse(User user) {
|
||||
UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
|
||||
@ -4309,6 +4319,10 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
}
|
||||
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) {
|
||||
usageRecResponse.setTags(resourceTagResponseMap.get(resourceId + ":" + resourceType));
|
||||
@ -5109,4 +5123,40 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
|
||||
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.snapshot.ListSnapshotsCmdByAdmin;
|
||||
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.ListStoragePoolsCmd;
|
||||
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.ListResponse;
|
||||
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.ProjectInvitationResponse;
|
||||
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.query.QueryService;
|
||||
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.SnapshotDataStoreDao;
|
||||
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.dao.ServiceOfferingDao;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||
import com.cloud.storage.BucketVO;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.ScopeType;
|
||||
@ -275,6 +280,7 @@ import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeApiServiceImpl;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.BucketDao;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.StoragePoolTagsDao;
|
||||
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.UserVmDao;
|
||||
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;
|
||||
|
||||
@ -543,6 +551,12 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
@Inject
|
||||
private SnapshotJoinDao snapshotJoinDao;
|
||||
|
||||
@Inject
|
||||
private ObjectStoreDao objectStoreDao;
|
||||
|
||||
@Inject
|
||||
private BucketDao bucketDao;
|
||||
|
||||
@Inject
|
||||
EntityManager entityManager;
|
||||
|
||||
@ -5030,6 +5044,158 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
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
|
||||
public String getConfigComponentName() {
|
||||
return QueryService.class.getSimpleName();
|
||||
|
||||
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
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.ImageStoreResponse;
|
||||
import org.apache.cloudstack.api.response.InstanceGroupResponse;
|
||||
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
@ -58,6 +60,7 @@ import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.storage.datastore.db.ObjectStoreVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
@ -659,4 +662,20 @@ public class ViewResponseHelper {
|
||||
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.storage.AddImageStoreCmd;
|
||||
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.CreateSecondaryStagingStoreCmd;
|
||||
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.DeleteObjectStoragePoolCmd;
|
||||
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.FindStoragePoolsForMigrationCmd;
|
||||
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.ListStoragePoolsCmd;
|
||||
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.UpdateCloudToUseObjectStoreCmd;
|
||||
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.UpdateStoragePoolCmd;
|
||||
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.UpdateAutoScaleVmProfileCmd;
|
||||
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.consoleproxy.CreateConsoleEndpointCmd;
|
||||
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(ListUserDataCmd.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;
|
||||
}
|
||||
|
||||
|
||||
@ -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.CreateStoragePoolCmd;
|
||||
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.DeleteSecondaryStagingStoreCmd;
|
||||
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.context.CallContext;
|
||||
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.ImageStoreObjectDownloadVO;
|
||||
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.SnapshotDataStoreDao;
|
||||
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.VolumeDataStoreVO;
|
||||
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.commons.collections.CollectionUtils;
|
||||
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.StoragePoolType;
|
||||
import com.cloud.storage.Volume.Type;
|
||||
import com.cloud.storage.dao.BucketDao;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
@ -353,6 +361,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
|
||||
@Inject
|
||||
protected UserVmManager userVmManager;
|
||||
@Inject
|
||||
protected ObjectStoreDao _objectStoreDao;
|
||||
|
||||
@Inject
|
||||
protected ObjectStoreDetailsDao _objectStoreDetailsDao;
|
||||
|
||||
@Inject
|
||||
protected BucketDao _bucketDao;
|
||||
protected List<StoragePoolDiscoverer> _discoverers;
|
||||
|
||||
public List<StoragePoolDiscoverer> getDiscoverers() {
|
||||
@ -3633,4 +3649,124 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
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.AUTOSCALE_VM_GROUP, ApiCommandResourceType.AutoScaleVmGroup);
|
||||
s_typeMap.put(EntityType.MANAGEMENT_SERVER, ApiCommandResourceType.Host);
|
||||
s_typeMap.put(EntityType.OBJECT_STORAGE, ApiCommandResourceType.ObjectStore);
|
||||
}
|
||||
|
||||
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"/>
|
||||
|
||||
<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="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.dao.NetworkVO;
|
||||
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.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
@ -40,12 +42,17 @@ import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
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.resource.ListDetailOptionsCmd;
|
||||
import org.apache.cloudstack.api.response.DetailOptionsResponse;
|
||||
import org.apache.cloudstack.api.response.EventResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ObjectStoreResponse;
|
||||
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.Before;
|
||||
import org.junit.Test;
|
||||
@ -66,6 +73,8 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@ -95,6 +104,12 @@ public class QueryManagerImplTest {
|
||||
@Mock
|
||||
SearchCriteria searchCriteriaMock;
|
||||
|
||||
@Mock
|
||||
ObjectStoreDao objectStoreDao;
|
||||
|
||||
@Mock
|
||||
BucketDao bucketDao;
|
||||
|
||||
private AccountVO account;
|
||||
private UserVO user;
|
||||
|
||||
@ -288,4 +303,41 @@ public class QueryManagerImplTest {
|
||||
|
||||
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