volume-upload: added account level secondary storage resource limit checks
diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
index 0a5f1d6..5d1e56b 100644
--- a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
+++ b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
@@ -49,6 +49,10 @@
 
     String description;
 
+    private String defaultMaxAccountSecondaryStorage;
+
+    private long accountId;
+
     public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo,
             String dataToRole) {
         this.entityId = entityId;
@@ -176,4 +180,20 @@
     public void setDescription(String description) {
         this.description = description;
     }
+
+    public void setDefaultMaxAccountSecondaryStorage(String defaultMaxAccountSecondaryStorage) {
+        this.defaultMaxAccountSecondaryStorage = defaultMaxAccountSecondaryStorage;
+    }
+
+    public String getDefaultMaxAccountSecondaryStorage() {
+        return defaultMaxAccountSecondaryStorage;
+    }
+
+    public void setAccountId(long accountId) {
+        this.accountId = accountId;
+    }
+
+    public long getAccountId() {
+        return accountId;
+    }
 }
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d7000f7..7e12284 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -339,6 +339,8 @@
                 command.setLocalPath(volumeStore.getLocalDownloadPath());
                 //using the existing max upload size configuration
                 command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
+                command.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()));
+                command.setAccountId(vol.getAccountId());
                 Gson gson = new GsonBuilder().create();
                 String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
                 response.setMetadata(metadata);
diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
index 265bc12..38a145b 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -270,6 +270,8 @@
                             templateOnStore.getDataStore().getRole().toString());
                     //using the existing max template size configuration
                     payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
+                    payload.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()));
+                    payload.setAccountId(template.getAccountId());
                     payload.setRemoteEndPoint(ep.getPublicAddr());
                     payload.setRequiresHvm(template.requiresHvm());
                     payload.setDescription(template.getDisplayText());
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 1cd69fc..bedd5c1 100755
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -48,6 +48,7 @@
 
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.storage.Storage;
+import com.cloud.storage.template.TemplateConstants;
 import com.cloud.utils.EncryptionUtil;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -2633,6 +2634,7 @@
                 updateStateMapWithError(uuid, errorMessage);
                 throw new InvalidParameterValueException(errorMessage);
             }
+            checkSecondaryStorageResourceLimit(cmd, contentLengthInGB);
             try {
                 String absolutePath = cmd.getAbsolutePath();
                 uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath);
@@ -2663,6 +2665,52 @@
         return uploadEntity;
     }
 
+    private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) {
+        String rootDir = this.getRootDir(cmd.getDataTo()) + File.separator;
+        long accountId = cmd.getAccountId();
+
+        long accountTemplateDirSize = 0;
+        File accountTemplateDir = new File(rootDir + getTemplatePathForAccount(accountId));
+        if(accountTemplateDir.exists()) {
+            FileUtils.sizeOfDirectory(accountTemplateDir);
+        }
+        long accountVolumeDirSize = 0;
+        File accountVolumeDir = new File(rootDir + getVolumePathForAccount(accountId));
+        if(accountVolumeDir.exists()) {
+            accountVolumeDirSize = FileUtils.sizeOfDirectory(accountVolumeDir);
+        }
+        long accountSnapshotDirSize = 0;
+        File accountSnapshotDir = new File(rootDir + getSnapshotPathForAccount(accountId));
+        if(accountSnapshotDir.exists()) {
+            accountSnapshotDirSize = FileUtils.sizeOfDirectory(accountSnapshotDir);
+        }
+        s_logger.debug("accountTemplateDirSize: " + accountTemplateDirSize + " accountSnapshotDirSize: " +accountSnapshotDirSize + " accountVolumeDirSize: " +
+                           accountVolumeDirSize);
+
+        int accountDirSizeInGB = getSizeInGB(accountTemplateDirSize + accountSnapshotDirSize + accountVolumeDirSize);
+        int defaultMaxAccountSecondaryStorageInGB = Integer.parseInt(cmd.getDefaultMaxAccountSecondaryStorage());
+
+        if ((accountDirSizeInGB + contentLengthInGB) > defaultMaxAccountSecondaryStorageInGB) {
+            s_logger.error("accountDirSizeInGb: " + accountDirSizeInGB + " defaultMaxAccountSecondaryStorageInGB: " + defaultMaxAccountSecondaryStorageInGB + " contentLengthInGB:"
+                    + contentLengthInGB);
+            String errorMessage = "Maximum number of resources of type secondary_storage for account has exceeded";
+            updateStateMapWithError(cmd.getEntityUUID(), errorMessage);
+            throw new InvalidParameterValueException(errorMessage);
+        }
+    }
+
+    private String getVolumePathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + accountId;
+    }
+
+    private String getTemplatePathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + accountId;
+    }
+
+    private String getSnapshotPathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId;
+    }
+
     private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) {
         String uuid = cmd.getEntityUUID();
         String uploadPath = this.getRootDir(cmd.getDataTo()) + File.separator + cmd.getAbsolutePath();