/* * Copyright 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.constraint.ContainmentConstraint; import com.emc.storageos.db.client.model.Bucket; import com.emc.storageos.db.client.model.DiscoveredDataObject.Type; import com.emc.storageos.db.client.model.ObjectBucketACL; import com.emc.storageos.db.client.model.ObjectUserSecretKey; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.util.CustomQueryUtility; import com.emc.storageos.model.object.BucketACE; import com.emc.storageos.model.object.BucketACL; import com.emc.storageos.model.object.BucketACLUpdateParams; import com.emc.storageos.svcs.errorhandling.resources.InternalException; import com.emc.storageos.volumecontroller.AsyncTask; import com.emc.storageos.volumecontroller.ControllerException; import com.emc.storageos.volumecontroller.ObjectController; import com.emc.storageos.volumecontroller.ObjectDeviceInputOutput; import com.emc.storageos.volumecontroller.ObjectStorageDevice; /** * Generic Object Controller Implementation that does all of the database * operations and calls methods on the array specific implementations */ public class ObjectDeviceController implements ObjectController { private DbClient _dbClient; private Map<String, ObjectStorageDevice> _devices; private static final Logger _log = LoggerFactory.getLogger(ObjectDeviceController.class); public void setDbClient(DbClient dbc) { _dbClient = dbc; } public void setDevices(Map<String, ObjectStorageDevice> deviceInterfaces) { _devices = deviceInterfaces; } private ObjectStorageDevice getDevice(String deviceType) { return _devices.get(deviceType); } @Override public void connectStorage(URI storage) throws InternalException { // TODO Auto-generated method stub _log.info("ObjectDeviceController:connectStorage"); } @Override public void disconnectStorage(URI storage) throws InternalException { // TODO Auto-generated method stub _log.info("ObjectDeviceController:disconnectStorage"); } @Override public void discoverStorageSystem(AsyncTask[] tasks) throws InternalException { // TODO Auto-generated method stub _log.info("ObjectDeviceController:discoverStorageSystem"); } @Override public void scanStorageProviders(AsyncTask[] tasks) throws InternalException { // TODO Auto-generated method stub _log.info("ObjectDeviceController:scanStorageProviders"); } @Override public void startMonitoring(AsyncTask task, Type deviceType) throws InternalException { // TODO Auto-generated method stub _log.info("ObjectDeviceController:startMonitoring"); } @Override public void createBucket(URI storage, URI uriPool, URI bkt, String label, String namespace, Integer retention, Long hardQuota, Long softQuota, String owner, String task) throws ControllerException { _log.info("ObjectDeviceController:createBucket Bucket URI : {} ", bkt); StorageSystem storageObj = _dbClient.queryObject(StorageSystem.class, storage); Bucket bucketObj = _dbClient.queryObject(Bucket.class, bkt); StoragePool stPool = _dbClient.queryObject(StoragePool.class, uriPool); ObjectDeviceInputOutput args = new ObjectDeviceInputOutput(); args.setName(label); args.setNamespace(namespace); args.setDevStoragePool(stPool.getNativeId()); // recommended storage pool args.setRetentionPeriod(retention); args.setBlkSizeHQ(hardQuota); args.setNotSizeSQ(softQuota); args.setOwner(owner); _log.info("ObjectDeviceController:createBucket URI and Type: " + storage.toString() + " " + storageObj.getSystemType()); BiosCommandResult result = getDevice(storageObj.getSystemType()).doCreateBucket(storageObj, bucketObj, args, task); if (result.getCommandPending()) { return; } bucketObj.getOpStatus().updateTaskStatus(task, result.toOperation()); } @Override public void deleteBucket(URI storage, URI bucket, String deleteType, String task) throws ControllerException { _log.info("ObjectDeviceController:deleteBucket Bucket URI : {} ", bucket); Bucket bucketObj = _dbClient.queryObject(Bucket.class, bucket); StorageSystem storageObj = _dbClient.queryObject(StorageSystem.class, storage); BiosCommandResult result = getDevice(storageObj.getSystemType()).doDeleteBucket(storageObj, bucketObj, deleteType, task); if (result.getCommandPending()) { return; } bucketObj.getOpStatus().updateTaskStatus(task, result.toOperation()); } @Override public void updateBucket(URI storage, URI bucket, Long softQuota, Long hardQuota, Integer retention, String task) throws ControllerException { _log.info("ObjectDeviceController:updateBucket Bucket URI : {} ", bucket); Bucket bucketObj = _dbClient.queryObject(Bucket.class, bucket); StorageSystem storageObj = _dbClient.queryObject(StorageSystem.class, storage); BiosCommandResult result = getDevice(storageObj.getSystemType()).doUpdateBucket(storageObj, bucketObj, softQuota, hardQuota, retention, task); if (result.getCommandPending()) { return; } bucketObj.getOpStatus().updateTaskStatus(task, result.toOperation()); } @Override public void updateBucketACL(URI storage, URI bucket, BucketACLUpdateParams param, String opId) throws InternalException { ControllerUtils.setThreadLocalLogData(bucket, opId); _log.info("ObjectDeviceController:updateBucketACL Bucket URI : {} ", bucket); Bucket bucketObj = _dbClient.queryObject(Bucket.class, bucket); StorageSystem storageObj = _dbClient.queryObject(StorageSystem.class, storage); ObjectDeviceInputOutput objectArgs = new ObjectDeviceInputOutput(); objectArgs.setAllBuckectAcl(param); objectArgs.setName(bucketObj.getName()); objectArgs.setNamespace(bucketObj.getNamespace()); // Query for existing ACL and setting it. objectArgs.setExistingBucketAcl(queryExistingBucketAcl(objectArgs,bucket)); BiosCommandResult result = getDevice(storageObj.getSystemType()).doUpdateBucketACL(storageObj, bucketObj, objectArgs, param, opId); if (result.getCommandPending()) { return; } bucketObj.getOpStatus().updateTaskStatus(opId, result.toOperation()); } @Override public void deleteBucketACL(URI storage, URI bucket, String opId) throws InternalException { ControllerUtils.setThreadLocalLogData(bucket, opId); _log.info("ObjectDeviceController:updateBucketACL Bucket URI : {} ", bucket); Bucket bucketObj = _dbClient.queryObject(Bucket.class, bucket); StorageSystem storageObj = _dbClient.queryObject(StorageSystem.class, storage); ObjectDeviceInputOutput objectArgs = new ObjectDeviceInputOutput(); objectArgs.setName(bucketObj.getName()); objectArgs.setNamespace(bucketObj.getNamespace()); // Query for existing ACL and setting it for deletion. objectArgs.setBucketAclToDelete(queryExistingBucketAcl(objectArgs,bucket)); BiosCommandResult result = getDevice(storageObj.getSystemType()).doDeleteBucketACL(storageObj, bucketObj, objectArgs, opId); if (result.getCommandPending()) { return; } bucketObj.getOpStatus().updateTaskStatus(opId, result.toOperation()); } @Override public void syncBucketACL(URI storage, URI bucketId, String opId) throws InternalException { ControllerUtils.setThreadLocalLogData(bucketId, opId); _log.info("ObjectDeviceController:updateBucketACL Bucket URI : {} ", bucketId); Bucket bucketObj = _dbClient.queryObject(Bucket.class, bucketId); StorageSystem storageObj = _dbClient.queryObject(StorageSystem.class, storage); ObjectDeviceInputOutput objectArgs = new ObjectDeviceInputOutput(); objectArgs.setName(bucketObj.getName()); objectArgs.setNamespace(bucketObj.getNamespace()); BiosCommandResult result = getDevice(storageObj.getSystemType()).doSyncBucketACL(storageObj, bucketObj, objectArgs, opId); if (result.getCommandPending()) { return; } bucketObj.getOpStatus().updateTaskStatus(opId, result.toOperation()); } private List<BucketACE> queryExistingBucketAcl(ObjectDeviceInputOutput args, URI buckeId) { _log.info("Querying ACL of Bucket {}", args.getName()); List<BucketACE> acl = new ArrayList<BucketACE>(); try { List<ObjectBucketACL> dbBucketAclList = queryDbBucketAcl(args,buckeId); Iterator<ObjectBucketACL> dbAclIter = dbBucketAclList.iterator(); while (dbAclIter.hasNext()) { ObjectBucketACL dbBucketAcl = dbAclIter.next(); BucketACE ace = new BucketACE(); ace.setDomain(dbBucketAcl.getDomain()); ace.setBucketName(dbBucketAcl.getBucketName()); ace.setGroup(dbBucketAcl.getGroup()); ace.setPermissions(dbBucketAcl.getPermissions()); ace.setNamespace(dbBucketAcl.getNamespace()); ace.setUser(dbBucketAcl.getUser()); ace.setCustomGroup(dbBucketAcl.getCustomGroup()); acl.add(ace); } } catch (Exception e) { _log.error("Error while querying ACL(s) of a share {}", e); } return acl; } private List<ObjectBucketACL> queryDbBucketAcl(ObjectDeviceInputOutput args, URI bucketId) { List<ObjectBucketACL> acls = new ArrayList<ObjectBucketACL>(); try { ContainmentConstraint containmentConstraint = null; _log.info("Querying DB for ACL of Bucket {} ", args.getName()); containmentConstraint = ContainmentConstraint.Factory.getBucketAclsConstraint(bucketId); List<ObjectBucketACL> bucketAclList = CustomQueryUtility.queryActiveResourcesByConstraint( _dbClient, ObjectBucketACL.class, containmentConstraint); Iterator<ObjectBucketACL> bucketAclIter = bucketAclList.iterator(); while (bucketAclIter.hasNext()) { ObjectBucketACL bucketAce = bucketAclIter.next(); if (args.getName().equals(bucketAce.getBucketName())) { acls.add(bucketAce); } } } catch (Exception e) { _log.error("Error while querying DB for ACL(s) of a share {}", e); } return acls; } @Override public ObjectUserSecretKey addUserSecretKey(URI storage, String userId, String secretKey) throws InternalException { StorageSystem storageObj = _dbClient.queryObject(StorageSystem.class, storage); return getDevice(storageObj.getSystemType()).doAddUserSecretKey(storageObj, userId, secretKey); } }