You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/01/15 03:04:54 UTC

[23/44] Revert "Merge remote-tracking branch 'origin/javelin' into javelin"

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index f3da368..afe985b 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -21,27 +21,30 @@ package org.apache.cloudstack.storage.volume;
 import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
 import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.async.AsyncRpcConext;
+import org.apache.cloudstack.storage.EndPoint;
+import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
+import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager;
+import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
 import org.apache.cloudstack.storage.image.TemplateInfo;
 import org.apache.cloudstack.storage.image.motion.ImageMotionService;
+import org.apache.cloudstack.storage.volume.VolumeService.VolumeApiResult;
 import org.apache.cloudstack.storage.volume.db.VolumeDao2;
 import org.apache.cloudstack.storage.volume.db.VolumeVO;
-import org.springframework.stereotype.Component;
 
+import org.springframework.stereotype.Component;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.Volume;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
 
 //1. change volume state
 //2. orchestrator of volume, control most of the information of volume, storage pool id, voluem state, scope etc.
@@ -51,13 +54,11 @@ public class VolumeServiceImpl implements VolumeService {
     @Inject
     VolumeDao2 volDao;
     @Inject
-    PrimaryDataStoreProviderManager dataStoreMgr;
+    PrimaryDataStoreManager dataStoreMgr;
     @Inject
     ObjectInDataStoreManager objectInDataStoreMgr;
     @Inject
     ImageMotionService imageMotion;
-    @Inject
-    TemplateInstallStrategy templateInstallStrategy;
 
     public VolumeServiceImpl() {
     }
@@ -86,7 +87,7 @@ public class VolumeServiceImpl implements VolumeService {
     }
     
     @Override
-    public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, long dataStoreId) {
+    public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType) {
         PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(dataStoreId);
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
         VolumeApiResult result = new VolumeApiResult(volume);
@@ -111,7 +112,7 @@ public class VolumeServiceImpl implements VolumeService {
         caller.setCallback(caller.getTarget().createVolumeCallback(null, null))
         .setContext(context);
         
-        //dataStore.createVolumeAsync(vo, null, caller);
+        dataStore.createVolumeAsync(vo, diskType, caller);
         return future;
     }
     
@@ -158,7 +159,7 @@ public class VolumeServiceImpl implements VolumeService {
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
         VolumeApiResult result = new VolumeApiResult(volume);
         
-        DataStore dataStore = vo.getDataStore();
+        PrimaryDataStore dataStore = vo.getDataStore();
         vo.stateTransit(Volume.Event.DestroyRequested);
         if (dataStore == null) {
             vo.stateTransit(Volume.Event.OperationSucceeded);
@@ -172,7 +173,7 @@ public class VolumeServiceImpl implements VolumeService {
         caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null))
             .setContext(context);
         
-        dataStore.getDriver().deleteAsync(volume, caller);
+        dataStore.deleteVolumeAsync(volume, caller);
         return future;
     }
     
@@ -236,19 +237,18 @@ public class VolumeServiceImpl implements VolumeService {
         return null;
     }
 
-    class CreateBaseImageContext<T> extends AsyncRpcConext<T> {
+    private class CreateBaseImageContext<T> extends AsyncRpcConext<T> {
         private final VolumeInfo volume;
         private final PrimaryDataStore dataStore;
-        private final TemplateInfo srcTemplate;
+        private final TemplateInfo template;
         private final AsyncCallFuture<VolumeApiResult> future;
-        public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, 
-                TemplateInfo srcTemplate,
+        public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateInfo template, 
                 AsyncCallFuture<VolumeApiResult> future) {
             super(callback);
             this.volume = volume;
             this.dataStore = datastore;
+            this.template = template;
             this.future = future;
-            this.srcTemplate = srcTemplate;
         }
         
         public VolumeInfo getVolume() {
@@ -258,9 +258,9 @@ public class VolumeServiceImpl implements VolumeService {
         public PrimaryDataStore getDataStore() {
             return this.dataStore;
         }
-
-        public TemplateInfo getSrcTemplate() {
-            return this.srcTemplate;
+        
+        public TemplateInfo getTemplate() {
+            return this.template;
         }
         
         public AsyncCallFuture<VolumeApiResult> getFuture() {
@@ -268,46 +268,48 @@ public class VolumeServiceImpl implements VolumeService {
         }
         
     }
-    
-    static class CreateBaseImageResult extends CommandResult {
-        final TemplateInfo template;
-        public CreateBaseImageResult(TemplateInfo template) {
-            super();
-            this.template = template;
-        }
-    }
-    
     @DB
     protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
-        CreateBaseImageContext<VolumeApiResult> context = new CreateBaseImageContext<VolumeApiResult>(null, volume, 
-                dataStore,
-                template,
-                future);
-        
-        AsyncCallbackDispatcher<VolumeServiceImpl, CreateBaseImageResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().createBaseImageCallback(null, null))
-        .setContext(context);
-        
-        templateInstallStrategy.installAsync(template, dataStore, caller);
+        TemplateInfo templateOnPrimaryStoreObj = objectInDataStoreMgr.create(template, dataStore);
+        /*templateOnPrimaryStoreObj.stateTransit(ObjectInDataStoreStateMachine.Event.CreateRequested);
+        templateOnPrimaryStoreObj.updateStatus(Status.CREATING);
+        try {
+            dataStore.installTemplate(templateOnPrimaryStoreObj);
+            templateOnPrimaryStoreObj.updateStatus(Status.CREATED);
+        } catch (Exception e) {
+            templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
+            templateOnPrimaryStoreObj.stateTransit(ObjectInDataStoreStateMachine.Event.OperationFailed);
+            VolumeApiResult result = new VolumeApiResult(volume);
+            result.setResult(e.toString());
+            future.complete(result);
+            return;
+        }
+
+        templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOAD_IN_PROGRESS);
+   */
+        CreateBaseImageContext<VolumeApiResult> context = new CreateBaseImageContext<VolumeApiResult>(null, volume, dataStore, templateOnPrimaryStoreObj, future);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().createBaseImageCallback(null, null))
+            .setContext(context);
+ 
+        objectInDataStoreMgr.update(templateOnPrimaryStoreObj, ObjectInDataStoreStateMachine.Event.CreateRequested);
+
+        imageMotion.copyTemplateAsync(templateOnPrimaryStoreObj, template, caller);
     }
 
     @DB
-    protected Void createBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateBaseImageResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
-        CreateBaseImageResult result = callback.getResult();
-        VolumeApiResult res = new VolumeApiResult(context.getVolume());
-        
-        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
-        if (!result.isSuccess()) {
-            res.setResult(result.getResult());
-            future.complete(res);
-            return null;
+    protected Void createBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
+        CommandResult result = callback.getResult();
+        TemplateInfo templateOnPrimaryStoreObj = context.getTemplate();
+        if (result.isSuccess()) {
+            objectInDataStoreMgr.update(templateOnPrimaryStoreObj, ObjectInDataStoreStateMachine.Event.OperationSuccessed);
+        } else {
+            objectInDataStoreMgr.update(templateOnPrimaryStoreObj, ObjectInDataStoreStateMachine.Event.OperationFailed);
         }
         
-        //now create volume on base image
-        TemplateInfo templateOnPrimaryStoreObj = result.template;
+        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
         VolumeInfo volume = context.getVolume();
         PrimaryDataStore pd = context.getDataStore();
-
         createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, pd, future);
         return null;
     }
@@ -343,22 +345,19 @@ public class VolumeServiceImpl implements VolumeService {
         }
 
         CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, vo, future);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller =  AsyncCallbackDispatcher.create(this);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller =  AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallback(null, null))
         .setContext(context);
 
-       pd.getDriver().copyAsync(volume, templateOnPrimaryStore, caller);
+        pd.createVoluemFromBaseImageAsync(volume, templateOnPrimaryStore, caller);
     }
     
     @DB
-    public Object createVolumeFromBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
+    public Object createVolumeFromBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
         VolumeObject vo = context.getVolumeObject();
-        CopyCommandResult result = callback.getResult();
+        CommandResult result = callback.getResult();
         VolumeApiResult volResult = new VolumeApiResult(vo);
         if (result.isSuccess()) {
-            if (result.getPath() != null) {
-                vo.setPath(result.getPath());
-            }
             vo.stateTransit(Volume.Event.OperationSucceeded); 
         } else {
             vo.stateTransit(Volume.Event.OperationFailed);
@@ -372,9 +371,9 @@ public class VolumeServiceImpl implements VolumeService {
 
     @DB
     @Override
-    public AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, TemplateInfo template) {
+    public AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template) {
         PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
-        TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId());
+        TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = pd.getTemplate(template);
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
         VolumeApiResult result = new VolumeApiResult(volume);
         

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java
index 829694b..4ad20d5 100644
--- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java
+++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java
@@ -18,8 +18,7 @@
  */
 package org.apache.cloudstack.storage.volume.test;
 
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 import java.util.HashMap;
 import java.util.List;
@@ -28,11 +27,14 @@ import java.util.Map;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.cloudstack.storage.datastore.provider.PrimaryDataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
+import org.apache.cloudstack.storage.datastore.configurator.PrimaryDataStoreConfigurator;
+import org.apache.cloudstack.storage.datastore.provider.PrimaryDataStoreProviderManager;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
@@ -43,15 +45,20 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations="classpath:/testContext.xml")
 public class ConfiguratorTest {
-
+    @Inject
+    @Qualifier("defaultProvider")
+    List<PrimaryDataStoreConfigurator> configurators;
+    
     @Inject 
     List<PrimaryDataStoreProvider> providers;
     
     @Inject
+    PrimaryDataStoreProviderManager providerMgr;
+    @Inject
     ClusterDao clusterDao;
     @Before
     public void setup() {
-      /*  ClusterVO cluster = new ClusterVO();
+        ClusterVO cluster = new ClusterVO();
         cluster.setHypervisorType(HypervisorType.XenServer.toString());
         Mockito.when(clusterDao.findById(Mockito.anyLong())).thenReturn(cluster);
         try {
@@ -59,13 +66,13 @@ public class ConfiguratorTest {
         } catch (ConfigurationException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
-        }*/
+        }
     }
     @Test
     public void testLoadConfigurator() {
-        /*for (PrimaryDataStoreConfigurator configurator : configurators) {
+        for (PrimaryDataStoreConfigurator configurator : configurators) {
             System.out.println(configurator.getClass().getName());
-        }*/
+        }
     }
     
     @Test
@@ -79,16 +86,16 @@ public class ConfiguratorTest {
     
     @Test
     public void getProvider() {
-       // assertNotNull(providerMgr.getDataStoreProvider("default primary data store provider"));
+        assertNotNull(providerMgr.getDataStoreProvider("default primary data store provider"));
     }
     
     @Test
     public void createDataStore() {
-        /*PrimaryDataStoreProvider provider = providerMgr.getDataStoreProvider("default primary data store provider");
+        PrimaryDataStoreProvider provider = providerMgr.getDataStoreProvider("default primary data store provider");
         Map<String, String> params = new HashMap<String, String>();
         params.put("url", "nfs://localhost/mnt");
         params.put("clusterId", "1");
         params.put("name", "nfsprimary");
-        assertNotNull(provider.registerDataStore(params));*/
+        assertNotNull(provider.registerDataStore(params));
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/engine/storage/volume/test/resource/testContext.xml
----------------------------------------------------------------------
diff --git a/engine/storage/volume/test/resource/testContext.xml b/engine/storage/volume/test/resource/testContext.xml
index 83fe842..67f2422 100644
--- a/engine/storage/volume/test/resource/testContext.xml
+++ b/engine/storage/volume/test/resource/testContext.xml
@@ -1,3 +1,21 @@
+<!--
+  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.
+-->
 <?xml version="1.0" encoding="UTF-8"?>
 <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"

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/framework/ipc/test/resources/SampleManagementServerAppContext.xml
----------------------------------------------------------------------
diff --git a/framework/ipc/test/resources/SampleManagementServerAppContext.xml b/framework/ipc/test/resources/SampleManagementServerAppContext.xml
index 4d5e044..4b1ff3e 100644
--- a/framework/ipc/test/resources/SampleManagementServerAppContext.xml
+++ b/framework/ipc/test/resources/SampleManagementServerAppContext.xml
@@ -1,3 +1,21 @@
+<!--
+  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.
+-->
 <?xml version="1.0" encoding="UTF-8"?>
 
 <beans xmlns="http://www.springframework.org/schema/beans"

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/framework/jobs/pom.xml
----------------------------------------------------------------------
diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml
old mode 100755
new mode 100644
index d2313be..8b12f5d
--- a/framework/jobs/pom.xml
+++ b/framework/jobs/pom.xml
@@ -1,3 +1,21 @@
+<!--
+  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>
   <groupId>org.apache.cloudstack</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/framework/rest/pom.xml
----------------------------------------------------------------------
diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml
index e9009bf..2f89056 100644
--- a/framework/rest/pom.xml
+++ b/framework/rest/pom.xml
@@ -1,3 +1,21 @@
+<!--
+  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>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/framework/rest/test/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java
----------------------------------------------------------------------
diff --git a/framework/rest/test/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java b/framework/rest/test/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java
index 52b2d7f..fef6ba2 100644
--- a/framework/rest/test/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java
+++ b/framework/rest/test/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java
@@ -1,3 +1,19 @@
+// 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.framework.ws.jackson;
 
 import java.io.IOException;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java
----------------------------------------------------------------------
diff --git a/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java b/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java
index 9236fba..2eaa6b0 100644
--- a/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java
+++ b/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java
@@ -16,164 +16,85 @@
 // under the License.
 package org.apache.cloudstack.acl;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
+import static org.apache.cloudstack.acl.RoleType.Admin;
+import static org.apache.cloudstack.acl.RoleType.DomainAdmin;
+import static org.apache.cloudstack.acl.RoleType.ResourceAdmin;
+import static org.apache.cloudstack.acl.RoleType.User;
+
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
+import java.util.Set;
 
 import javax.ejb.Local;
+import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
+import com.cloud.server.ManagementServer;
 import com.cloud.exception.PermissionDeniedException;
-import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
-import com.cloud.user.User;
-import com.cloud.utils.PropertiesUtil;
 import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.component.Inject;
+import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.component.PluggableService;
 
-/*
- * This is the default API access checker that grab's the user's account
- * based on the account type, access is granted referring to commands in all *.properties files.
- */
-
-@Local(value=APIAccessChecker.class)
-public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIAccessChecker {
+// This is the default API access checker that grab's the user's account
+// based on the account type, access is granted
+@Component
+@Local(value=APIChecker.class)
+public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIChecker {
 
     protected static final Logger s_logger = Logger.getLogger(StaticRoleBasedAPIAccessChecker.class);
-    public static final short ADMIN_COMMAND = 1;
-    public static final short DOMAIN_ADMIN_COMMAND = 4;
-    public static final short RESOURCE_DOMAIN_ADMIN_COMMAND = 2;
-    public static final short USER_COMMAND = 8;
-    private static List<String> s_userCommands = null;
-    private static List<String> s_resellerCommands = null; // AKA domain-admin
-    private static List<String> s_adminCommands = null;
-    private static List<String> s_resourceDomainAdminCommands = null;
-    private static List<String> s_allCommands = null;
 
-    protected @Inject AccountManager _accountMgr;
-    @Inject protected List<PluggableService> _services;
+    private static Map<RoleType, Set<String>> s_roleBasedApisMap =
+            new HashMap<RoleType, Set<String>>();
+
+    @Inject List<PluggableService> _services;
 
     protected StaticRoleBasedAPIAccessChecker() {
         super();
-        s_allCommands = new ArrayList<String>();
-        s_userCommands = new ArrayList<String>();
-        s_resellerCommands = new ArrayList<String>();
-        s_adminCommands = new ArrayList<String>();
-        s_resourceDomainAdminCommands = new ArrayList<String>();
+        for (RoleType roleType: RoleType.values())
+            s_roleBasedApisMap.put(roleType, new HashSet<String>());
     }
 
     @Override
-    public boolean canAccessAPI(User user, String apiCommandName)
-            throws PermissionDeniedException{
-
-        boolean commandExists = s_allCommands.contains(apiCommandName);
-
-        if(commandExists && user != null){
-            Long accountId = user.getAccountId();
-            Account userAccount = _accountMgr.getAccount(accountId);
-            short accountType = userAccount.getType();
-            return isCommandAvailableForAccount(accountType, apiCommandName);
+    public boolean checkAccess(RoleType roleType, String commandName)
+            throws PermissionDeniedException {
+        boolean isAllowed = s_roleBasedApisMap.get(roleType).contains(commandName);
+        if (!isAllowed) {
+            throw new PermissionDeniedException("The API does not exist or is blacklisted. Role type=" + roleType.toString() + " is not allowed to request the api: " + commandName);
         }
-
-        return commandExists;
-    }
-
-    private static boolean isCommandAvailableForAccount(short accountType, String commandName) {
-        boolean isCommandAvailable = false;
-        switch (accountType) {
-        case Account.ACCOUNT_TYPE_ADMIN:
-            isCommandAvailable = s_adminCommands.contains(commandName);
-            break;
-        case Account.ACCOUNT_TYPE_DOMAIN_ADMIN:
-            isCommandAvailable = s_resellerCommands.contains(commandName);
-            break;
-        case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN:
-            isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName);
-            break;
-        case Account.ACCOUNT_TYPE_NORMAL:
-            isCommandAvailable = s_userCommands.contains(commandName);
-            break;
-        }
-        return isCommandAvailable;
+        return isAllowed;
     }
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
         super.configure(name, params);
-
-        List<String> configFiles = new ArrayList<String>();
+        _services.add((PluggableService) ComponentContext.getComponent(ManagementServer.Name));
         for (PluggableService service : _services) {
-            configFiles.addAll(Arrays.asList(service.getPropertiesFiles()));
+            processConfigFiles(service.getProperties(), service.getClass().toString());
+            s_logger.info("Processed role based acl for: " + service.toString());
         }
-
-        processConfigFiles(configFiles);
         return true;
     }
 
-    private void processConfigFiles(List<String> configFiles) {
-        Properties preProcessedCommands = new Properties();
-
-        for (String configFile : configFiles) {
-            File commandsFile = PropertiesUtil.findConfigFile(configFile);
-            if (commandsFile != null) {
-                try {
-                    preProcessedCommands.load(new FileInputStream(commandsFile));
-                } catch (FileNotFoundException fnfex) {
-                    // in case of a file within a jar in classpath, try to open stream using url
-                    InputStream stream = PropertiesUtil.openStreamFromURL(configFile);
-                    if (stream != null) {
-                        try {
-                            preProcessedCommands.load(stream);
-                        } catch (IOException e) {
-                            s_logger.error("IO Exception, unable to find properties file:", fnfex);
-                        }
-                    } else {
-                        s_logger.error("Unable to find properites file", fnfex);
-                    }
-                } catch (IOException ioe) {
-                    s_logger.error("IO Exception loading properties file", ioe);
-                }
-            }
-        }
-
-        for (Object key : preProcessedCommands.keySet()) {
-            String preProcessedCommand = preProcessedCommands.getProperty((String) key);
-            int splitIndex = preProcessedCommand.lastIndexOf(";");
-            // Backward compatible to old style, apiname=pkg;mask
-            String mask = preProcessedCommand.substring(splitIndex+1);
-
+    private void processConfigFiles(Map<String, String> configMap, String service) {
+        for (Map.Entry<String, String> entry: configMap.entrySet()) {
+            String apiName = entry.getKey();
+            String roleMask = entry.getValue();
             try {
-                short cmdPermissions = Short.parseShort(mask);
-                if ((cmdPermissions & ADMIN_COMMAND) != 0) {
-                    s_adminCommands.add((String) key);
-                }
-                if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) {
-                    s_resourceDomainAdminCommands.add((String) key);
-                }
-                if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) {
-                    s_resellerCommands.add((String) key);
+                short cmdPermissions = Short.parseShort(roleMask);
+                for (RoleType roleType: RoleType.values()) {
+                    if ((cmdPermissions & roleType.getValue()) != 0)
+                        s_roleBasedApisMap.get(roleType).add(apiName);
                 }
-                if ((cmdPermissions & USER_COMMAND) != 0) {
-                    s_userCommands.add((String) key);
-                }
-                s_allCommands.addAll(s_adminCommands);
-                s_allCommands.addAll(s_resourceDomainAdminCommands);
-                s_allCommands.addAll(s_userCommands);
-                s_allCommands.addAll(s_resellerCommands);
             } catch (NumberFormatException nfe) {
-                s_logger.info("Malformed command.properties permissions value, key = " + key + ", value = " + preProcessedCommand);
+                s_logger.info("Malformed getProperties() value for service: " + service
+                        + " for entry: " + entry.toString());
             }
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/api/discovery/src/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java
----------------------------------------------------------------------
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java b/plugins/api/discovery/src/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java
index dcbaec1..ed3e175 100644
--- a/plugins/api/discovery/src/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java
+++ b/plugins/api/discovery/src/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java
@@ -16,9 +16,12 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.discovery;
 
+import com.cloud.user.UserContext;
+import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.PlugService;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.ListResponse;
@@ -27,8 +30,8 @@ import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
 
 import org.apache.log4j.Logger;
 
-@APICommand(name = "listApis", responseObject = ApiDiscoveryResponse.class, description = "lists all available apis on the server, provided by Api Discovery plugin", since = "4.1.0")
-public class ListApisCmd extends BaseListCmd {
+@APICommand(name = "listApis", responseObject = ApiDiscoveryResponse.class, description = "lists all available apis on the server, provided by the Api Discovery plugin", since = "4.1.0")
+public class ListApisCmd extends BaseCmd {
 
     public static final Logger s_logger = Logger.getLogger(ListApisCmd.class.getName());
     private static final String s_name = "listapisresponse";
@@ -36,12 +39,16 @@ public class ListApisCmd extends BaseListCmd {
     @PlugService
     ApiDiscoveryService _apiDiscoveryService;
 
+    @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="API name")
+    private String name;
+
     @Override
     public void execute() throws ServerApiException {
         if (_apiDiscoveryService != null) {
-            ListResponse<ApiDiscoveryResponse> response = (ListResponse<ApiDiscoveryResponse>) _apiDiscoveryService.listApis();
+            RoleType roleType = _accountService.getRoleType(UserContext.current().getCaller());
+            ListResponse<ApiDiscoveryResponse> response = (ListResponse<ApiDiscoveryResponse>) _apiDiscoveryService.listApis(roleType, name);
             if (response == null) {
-                throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Api Discovery plugin was unable to find and process any apis");
+                throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Api Discovery plugin was unable to find an api by that name or process any apis");
             }
             response.setResponseName(getCommandName());
             this.setResponseObject(response);
@@ -52,4 +59,10 @@ public class ListApisCmd extends BaseListCmd {
     public String getCommandName() {
         return s_name;
     }
+
+    @Override
+    public long getEntityOwnerId() {
+        // no owner is needed for list command
+        return 0;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java
----------------------------------------------------------------------
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java b/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java
index dd1298b..de6a9f9 100644
--- a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java
+++ b/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java
@@ -16,18 +16,15 @@
 // under the License.
 package org.apache.cloudstack.api.response;
 
-import com.cloud.user.Account;
 import org.apache.cloudstack.api.ApiConstants;
 import com.cloud.serializer.Param;
 import com.google.gson.annotations.SerializedName;
 import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
 
 import java.util.HashSet;
 import java.util.Set;
 
 @SuppressWarnings("unused")
-@EntityReference(value = Account.class)
 public class ApiDiscoveryResponse extends BaseResponse {
     @SerializedName(ApiConstants.NAME) @Param(description="the name of the api command")
     private String name;
@@ -41,11 +38,18 @@ public class ApiDiscoveryResponse extends BaseResponse {
     @SerializedName(ApiConstants.IS_ASYNC) @Param(description="true if api is asynchronous")
     private Boolean isAsync;
 
+    @SerializedName("related") @Param(description="comma separated related apis")
+    private String related;
+
     @SerializedName(ApiConstants.PARAMS)  @Param(description="the list params the api accepts", responseObject = ApiParameterResponse.class)
     private Set<ApiParameterResponse> params;
 
+    @SerializedName(ApiConstants.RESPONSE)  @Param(description="api response fields", responseObject = ApiResponseResponse.class)
+    private Set<ApiResponseResponse> apiResponse;
+
     public ApiDiscoveryResponse(){
         params = new HashSet<ApiParameterResponse>();
+        apiResponse = new HashSet<ApiResponseResponse>();
         isAsync = false;
     }
 
@@ -65,6 +69,18 @@ public class ApiDiscoveryResponse extends BaseResponse {
         this.isAsync = isAsync;
     }
 
+    public String getRelated() {
+        return related;
+    }
+
+    public void setRelated(String related) {
+        this.related = related;
+    }
+
+    public Set<ApiParameterResponse> getParams() {
+        return params;
+    }
+
     public void setParams(Set<ApiParameterResponse> params) {
         this.params = params;
     }
@@ -72,4 +88,8 @@ public class ApiDiscoveryResponse extends BaseResponse {
     public void addParam(ApiParameterResponse param) {
         this.params.add(param);
     }
+
+    public void addApiResponse(ApiResponseResponse apiResponse) {
+        this.apiResponse.add(apiResponse);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiParameterResponse.java
----------------------------------------------------------------------
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiParameterResponse.java b/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiParameterResponse.java
index 9138288..fa6dc17 100644
--- a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiParameterResponse.java
+++ b/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiParameterResponse.java
@@ -40,6 +40,9 @@ public class ApiParameterResponse extends BaseResponse {
     @SerializedName(ApiConstants.SINCE) @Param(description="version of CloudStack the api was introduced in")
     private String since;
 
+    @SerializedName("related") @Param(description="comma separated related apis to get the parameter")
+    private String related;
+
     public ApiParameterResponse(){
     }
 
@@ -67,4 +70,12 @@ public class ApiParameterResponse extends BaseResponse {
         this.since = since;
     }
 
+    public String getRelated() {
+        return related;
+    }
+
+    public void setRelated(String related) {
+        this.related = related;
+    }
+
  }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiResponseResponse.java
----------------------------------------------------------------------
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiResponseResponse.java b/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiResponseResponse.java
new file mode 100644
index 0000000..b96295e
--- /dev/null
+++ b/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiResponseResponse.java
@@ -0,0 +1,45 @@
+// 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 org.apache.cloudstack.api.ApiConstants;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.BaseResponse;
+
+public class ApiResponseResponse extends BaseResponse {
+    @SerializedName(ApiConstants.NAME) @Param(description="the name of the api response field")
+    private String name;
+
+    @SerializedName(ApiConstants.DESCRIPTION) @Param(description="description of the api response field")
+    private String description;
+
+    @SerializedName(ApiConstants.TYPE) @Param(description="response field type")
+    private String type;
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryService.java
----------------------------------------------------------------------
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryService.java b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryService.java
new file mode 100644
index 0000000..611493b
--- /dev/null
+++ b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryService.java
@@ -0,0 +1,26 @@
+// 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.discovery;
+
+import com.cloud.utils.component.PluggableService;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+
+public interface ApiDiscoveryService extends PluggableService {
+    ListResponse<? extends BaseResponse> listApis(RoleType roleType, String apiName);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java
----------------------------------------------------------------------
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java
index 5363e55..6ff4085 100644
--- a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java
+++ b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java
@@ -16,8 +16,14 @@
 // under the License.
 package org.apache.cloudstack.discovery;
 
+import com.cloud.serializer.Param;
+import com.cloud.server.ManagementServer;
 import com.cloud.utils.ReflectUtil;
-import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.PluggableService;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.BaseAsyncCmd;
@@ -26,54 +32,77 @@ import org.apache.cloudstack.api.BaseResponse;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
 import org.apache.cloudstack.api.response.ApiParameterResponse;
+import org.apache.cloudstack.api.response.ApiResponseResponse;
 import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
 import javax.ejb.Local;
-import javax.naming.ConfigurationException;
+import javax.inject.Inject;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+@Component
 @Local(value = ApiDiscoveryService.class)
-public class ApiDiscoveryServiceImpl extends AdapterBase implements ApiDiscoveryService {
-
+public class ApiDiscoveryServiceImpl implements ApiDiscoveryService {
     private static final Logger s_logger = Logger.getLogger(ApiDiscoveryServiceImpl.class);
-    private Map<String, Class<?>> _apiNameCmdClassMap;
-    private ListResponse<ApiDiscoveryResponse> _discoveryResponse;
+
+    private static Map<RoleType, List<ApiDiscoveryResponse>> _roleTypeDiscoveryResponseListMap;
+
+    private static Map<String, ApiDiscoveryResponse> _apiNameDiscoveryResponseMap =
+            new HashMap<String, ApiDiscoveryResponse>();
+
+    private static Map<String, List<RoleType>> _apiNameRoleTypeListMap = null;
+
+    @Inject List<PluggableService> _services;
 
     protected ApiDiscoveryServiceImpl() {
         super();
+        if (_roleTypeDiscoveryResponseListMap == null) {
+            long startTime = System.nanoTime();
+            _roleTypeDiscoveryResponseListMap = new HashMap<RoleType, List<ApiDiscoveryResponse>>();
+            for (RoleType roleType: RoleType.values())
+                _roleTypeDiscoveryResponseListMap.put(roleType, new ArrayList<ApiDiscoveryResponse>());
+            cacheResponseMap();
+            long endTime = System.nanoTime();
+            s_logger.info("Api Discovery Service: Annotation, docstrings, api relation graph processed in " + (endTime - startTime) / 1000000.0 + " ms");
+        }
     }
 
-    private void generateApiNameCmdClassMapping() {
-        _apiNameCmdClassMap = new HashMap<String, Class<?>>();
-        Set<Class<?>> cmdClasses = ReflectUtil.getClassesWithAnnotation(APICommand.class, new String[]{"org.apache.cloudstack.api", "com.cloud.api"});
-
-        for(Class<?> cmdClass: cmdClasses) {
-            String apiName = cmdClass.getAnnotation(APICommand.class).name();
-            if (_apiNameCmdClassMap.containsKey(apiName)) {
-                s_logger.error("API Cmd class " + cmdClass.getName() + " has non-unique apiname" + apiName);
-                continue;
+    private Map<String, List<RoleType>> getApiNameRoleTypeListMap() {
+        Map<String, List<RoleType>> apiNameRoleTypeMap = new HashMap<String, List<RoleType>>();
+        _services.add((PluggableService) ComponentContext.getComponent(ManagementServer.Name));
+        for (PluggableService service : _services) {
+            for (Map.Entry<String, String> entry: service.getProperties().entrySet()) {
+                String apiName = entry.getKey();
+                String roleMask = entry.getValue();
+                try {
+                    short cmdPermissions = Short.parseShort(roleMask);
+                    if (!apiNameRoleTypeMap.containsKey(apiName))
+                        apiNameRoleTypeMap.put(apiName, new ArrayList<RoleType>());
+                    for (RoleType roleType: RoleType.values()) {
+                        if ((cmdPermissions & roleType.getValue()) != 0)
+                            apiNameRoleTypeMap.get(apiName).add(roleType);
+                    }
+                } catch (NumberFormatException nfe) {
+                }
             }
-            _apiNameCmdClassMap.put(apiName, cmdClass);
         }
+        return apiNameRoleTypeMap;
     }
 
-    private void precacheListApiResponse() {
-
-        if(_apiNameCmdClassMap == null)
-            return;
-
-        _discoveryResponse = new ListResponse<ApiDiscoveryResponse>();
+    private void cacheResponseMap() {
+        Set<Class<?>> cmdClasses = ReflectUtil.getClassesWithAnnotation(APICommand.class,
+                new String[]{"org.apache.cloudstack.api", "com.cloud.api"});
 
-        List<ApiDiscoveryResponse> apiDiscoveryResponses = new ArrayList<ApiDiscoveryResponse>();
+        Map<String, List<String>> responseApiNameListMap = new HashMap<String, List<String>>();
 
-        for(String key: _apiNameCmdClassMap.keySet()) {
-            Class<?> cmdClass = _apiNameCmdClassMap.get(key);
+        for(Class<?> cmdClass: cmdClasses) {
             APICommand apiCmdAnnotation = cmdClass.getAnnotation(APICommand.class);
             if (apiCmdAnnotation == null)
                 apiCmdAnnotation = cmdClass.getSuperclass().getAnnotation(APICommand.class);
@@ -82,10 +111,33 @@ public class ApiDiscoveryServiceImpl extends AdapterBase implements ApiDiscovery
                     || apiCmdAnnotation.name().isEmpty())
                 continue;
 
+            String apiName = apiCmdAnnotation.name();
+            String responseName = apiCmdAnnotation.responseObject().getName();
+            if (!responseName.contains("SuccessResponse")) {
+                if (!responseApiNameListMap.containsKey(responseName))
+                    responseApiNameListMap.put(responseName, new ArrayList<String>());
+                responseApiNameListMap.get(responseName).add(apiName);
+            }
             ApiDiscoveryResponse response = new ApiDiscoveryResponse();
-            response.setName(apiCmdAnnotation.name());
+            response.setName(apiName);
             response.setDescription(apiCmdAnnotation.description());
-            response.setSince(apiCmdAnnotation.since());
+            if (!apiCmdAnnotation.since().isEmpty())
+                response.setSince(apiCmdAnnotation.since());
+            response.setRelated(responseName);
+
+            Field[] responseFields = apiCmdAnnotation.responseObject().getDeclaredFields();
+            for(Field responseField: responseFields) {
+                SerializedName serializedName = responseField.getAnnotation(SerializedName.class);
+                if(serializedName != null) {
+                    ApiResponseResponse responseResponse = new ApiResponseResponse();
+                    responseResponse.setName(serializedName.value());
+                    Param param = responseField.getAnnotation(Param.class);
+                    if (param != null)
+                        responseResponse.setDescription(param.description());
+                    responseResponse.setType(responseField.getType().getSimpleName().toLowerCase());
+                    response.addApiResponse(responseResponse);
+                }
+            }
 
             Field[] fields = ReflectUtil.getAllFieldsForClass(cmdClass,
                     new Class<?>[] {BaseCmd.class, BaseAsyncCmd.class, BaseAsyncCreateCmd.class});
@@ -104,41 +156,80 @@ public class ApiDiscoveryServiceImpl extends AdapterBase implements ApiDiscovery
                     ApiParameterResponse paramResponse = new ApiParameterResponse();
                     paramResponse.setName(parameterAnnotation.name());
                     paramResponse.setDescription(parameterAnnotation.description());
-                    paramResponse.setType(parameterAnnotation.type().toString());
+                    paramResponse.setType(parameterAnnotation.type().toString().toLowerCase());
                     paramResponse.setLength(parameterAnnotation.length());
                     paramResponse.setRequired(parameterAnnotation.required());
-                    paramResponse.setSince(parameterAnnotation.since());
+                    if (!parameterAnnotation.since().isEmpty())
+                        paramResponse.setSince(parameterAnnotation.since());
+                    paramResponse.setRelated(parameterAnnotation.entityType()[0].getName());
                     response.addParam(paramResponse);
                 }
             }
-            response.setObjectName("apis");
-            apiDiscoveryResponses.add(response);
+            response.setObjectName("api");
+            _apiNameDiscoveryResponseMap.put(apiName, response);
+        }
+
+        for (String apiName: _apiNameDiscoveryResponseMap.keySet()) {
+            ApiDiscoveryResponse response = _apiNameDiscoveryResponseMap.get(apiName);
+            Set<ApiParameterResponse> processedParams = new HashSet<ApiParameterResponse>();
+            for (ApiParameterResponse param: response.getParams()) {
+                if (responseApiNameListMap.containsKey(param.getRelated())) {
+                    List<String> relatedApis = responseApiNameListMap.get(param.getRelated());
+                    param.setRelated(StringUtils.join(relatedApis, ","));
+                } else {
+                    param.setRelated(null);
+                }
+                processedParams.add(param);
+            }
+            response.setParams(processedParams);
+
+            if (responseApiNameListMap.containsKey(response.getRelated())) {
+                List<String> relatedApis = responseApiNameListMap.get(response.getRelated());
+                relatedApis.remove(apiName);
+                response.setRelated(StringUtils.join(relatedApis, ","));
+            } else {
+                response.setRelated(null);
+            }
+            _apiNameDiscoveryResponseMap.put(apiName, response);
         }
-        _discoveryResponse.setResponses(apiDiscoveryResponses);
     }
 
     @Override
-    public boolean configure(String name, Map<String, Object> params)
-            throws ConfigurationException {
-        super.configure(name, params);
-
-        generateApiNameCmdClassMapping();
-        precacheListApiResponse();
-
-        return true;
-    }
+    public ListResponse<? extends BaseResponse> listApis(RoleType roleType, String name) {
+        // Creates roles based response list cache the first time listApis is called
+        // Due to how adapters work, this cannot be done when mgmt loads
+        if (_apiNameRoleTypeListMap == null) {
+            long startTime = System.nanoTime();
+            _apiNameRoleTypeListMap = getApiNameRoleTypeListMap();
+            for (Map.Entry<String, List<RoleType>> entry: _apiNameRoleTypeListMap.entrySet()) {
+                String apiName = entry.getKey();
+                for (RoleType roleTypeInList: entry.getValue()) {
+                    _roleTypeDiscoveryResponseListMap.get(roleTypeInList).add(
+                            _apiNameDiscoveryResponseMap.get(apiName));
+                }
+            }
+            long endTime = System.nanoTime();
+            s_logger.info("Api Discovery Service: List apis cached in " + (endTime - startTime) / 1000000.0 + " ms");
+        }
+        ListResponse<ApiDiscoveryResponse> response = new ListResponse<ApiDiscoveryResponse>();
+        if (name != null) {
+            if (!_apiNameDiscoveryResponseMap.containsKey(name))
+                return null;
 
-    public Map<String, Class<?>> getApiNameCmdClassMapping() {
-        return _apiNameCmdClassMap;
-    }
+             List<ApiDiscoveryResponse> singleResponse = new ArrayList<ApiDiscoveryResponse>();
+            singleResponse.add(_apiNameDiscoveryResponseMap.get(name));
+            response.setResponses(singleResponse);
 
-    @Override
-    public ListResponse<? extends BaseResponse> listApis() {
-        return _discoveryResponse;
+        } else {
+            response.setResponses(_roleTypeDiscoveryResponseListMap.get(roleType));
+        }
+        return response;
     }
 
     @Override
-    public String[] getPropertiesFiles() {
-        return new String[] { "api-discovery_commands.properties" };
+    public Map<String, String> getProperties() {
+        Map<String, String> apiDiscoveryPropertyMap = new HashMap<String, String>();
+        apiDiscoveryPropertyMap.put("listApis", "15");
+        return apiDiscoveryPropertyMap;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java
index c87c924..64865bb 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java
@@ -29,7 +29,7 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.AssociateLunCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "associateLun", description="Associate a LUN with a guest IQN", responseObject = AssociateLunCmdResponse.class)
 public class AssociateLunCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java
index 8c89730..c8d8d04 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java
@@ -33,7 +33,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.CreateLunCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "createLunOnFiler", description="Create a LUN from a pool", responseObject = CreateLunCmdResponse.class)
 public class CreateLunCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java
index a2d4b96..72a9efa 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java
@@ -32,7 +32,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.CreateVolumeOnFilerCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "createVolumeOnFiler", description="Create a volume", responseObject = CreateVolumeOnFilerCmdResponse.class)
 public class CreateVolumeOnFilerCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java
index 9e38c5f..f7ff567 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java
@@ -31,7 +31,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.CreateVolumePoolCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "createPool", description="Create a pool", responseObject = CreateVolumePoolCmdResponse.class)
 public class CreateVolumePoolCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java
index 1105ea5..7106c58 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java
@@ -33,7 +33,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.DeleteVolumePoolCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "deletePool", description="Delete a pool", responseObject = DeleteVolumePoolCmdResponse.class)
 public class DeleteVolumePoolCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java
index c5f7b11..8afd143 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java
@@ -33,7 +33,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.DeleteLUNCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "destroyLunOnFiler", description="Destroy a LUN", responseObject = DeleteLUNCmdResponse.class)
 public class DestroyLunCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java
index 4ddc0c9..730f1c0 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java
@@ -31,7 +31,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.DeleteVolumeOnFilerCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "destroyVolumeOnFiler", description="Destroy a Volume", responseObject = DeleteVolumeOnFilerCmdResponse.class)
 public class DestroyVolumeOnFilerCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java
index 0a6c1a7..5061f49 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java
@@ -30,7 +30,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.DissociateLunCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "dissociateLun", description="Dissociate a LUN", responseObject = DissociateLunCmdResponse.class)
 public class DissociateLunCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java
index 630b149..7c2ed45 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java
@@ -36,7 +36,7 @@ import com.cloud.netapp.LunVO;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.ListLunsCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "listLunsOnFiler", description="List LUN", responseObject = ListLunsCmdResponse.class)
 public class ListLunsCmd extends BaseCmd 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java
index d77f4fa..5857f43 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java
@@ -34,7 +34,7 @@ import com.cloud.netapp.NetappManager;
 import com.cloud.netapp.PoolVO;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.ListVolumePoolsCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "listPools", description="List Pool", responseObject = ListVolumePoolsCmdResponse.class)
 public class ListVolumePoolsCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java
index 66a96f3..17548cd 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java
@@ -33,7 +33,7 @@ import com.cloud.netapp.NetappManager;
 import com.cloud.netapp.NetappVolumeVO;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.ListVolumesOnFilerCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "listVolumesOnFiler", description="List Volumes", responseObject = ListVolumesOnFilerCmdResponse.class)
 public class ListVolumesOnFilerCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java
index 3e32cae..6282a64 100644
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java
+++ b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java
@@ -31,7 +31,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.netapp.NetappManager;
 import com.cloud.server.ManagementService;
 import com.cloud.server.api.response.netapp.ModifyVolumePoolCmdResponse;
-import com.cloud.utils.component.ComponentLocator;
+
 
 @APICommand(name = "modifyPool", description="Modify pool", responseObject = ModifyVolumePoolCmdResponse.class)
 public class ModifyVolumePoolCmd extends BaseCmd {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java
index f98a15c..7fe22dd 100644
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java
+++ b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java
@@ -662,7 +662,7 @@ public class NetappManagerImpl implements NetappManager
     		lun = _lunDao.persist(lun);
     		
     		//Lun id created: 6 digits right justified eg. 000045
-    		String lunIdStr = lun.getId().toString();
+    		String lunIdStr = String.valueOf(lun.getId());
     		String zeroStr = "000000";
     		int length = lunIdStr.length();
     		int offset = 6-length;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/plugins/host-allocators/random/src/com/cloud/agent/manager/allocator/impl/RandomAllocator.java
----------------------------------------------------------------------
diff --git a/plugins/host-allocators/random/src/com/cloud/agent/manager/allocator/impl/RandomAllocator.java b/plugins/host-allocators/random/src/com/cloud/agent/manager/allocator/impl/RandomAllocator.java
index 241b114..c302cdd 100755
--- a/plugins/host-allocators/random/src/com/cloud/agent/manager/allocator/impl/RandomAllocator.java
+++ b/plugins/host-allocators/random/src/com/cloud/agent/manager/allocator/impl/RandomAllocator.java
@@ -36,7 +36,6 @@ import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.resource.ResourceManager;
-import com.cloud.utils.component.ComponentLocator;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachineProfile;
 
@@ -53,39 +52,39 @@ public class RandomAllocator implements HostAllocator {
             ExcludeList avoid, int returnUpTo) {
         return allocateTo(vmProfile, plan, type, avoid, returnUpTo, true);
     }
-    
+
     @Override
     public List<Host> allocateTo(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, Type type,
-			ExcludeList avoid, int returnUpTo, boolean considerReservedCapacity) {
-
-		long dcId = plan.getDataCenterId();
-		Long podId = plan.getPodId();
-		Long clusterId = plan.getClusterId();
-		ServiceOffering offering = vmProfile.getServiceOffering();
-    	
-    	List<Host> suitableHosts = new ArrayList<Host>();
-    	
+            ExcludeList avoid, int returnUpTo, boolean considerReservedCapacity) {
+
+        long dcId = plan.getDataCenterId();
+        Long podId = plan.getPodId();
+        Long clusterId = plan.getClusterId();
+        ServiceOffering offering = vmProfile.getServiceOffering();
+
+        List<Host> suitableHosts = new ArrayList<Host>();
+
         if (type == Host.Type.Storage) {
             return suitableHosts;
         }
 
         String hostTag = offering.getHostTag();
         if(hostTag != null){
-        	s_logger.debug("Looking for hosts in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId + " having host tag:" + hostTag);
+            s_logger.debug("Looking for hosts in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId + " having host tag:" + hostTag);
         }else{
-        	s_logger.debug("Looking for hosts in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId);
+            s_logger.debug("Looking for hosts in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId);
         }
 
         // list all computing hosts, regardless of whether they support routing...it's random after all
         List<? extends Host> hosts = new ArrayList<HostVO>();
         if(hostTag != null){
-        	hosts = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
+            hosts = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
         }else{
-        	hosts = _resourceMgr.listAllUpAndEnabledHosts(type, clusterId, podId, dcId);
+            hosts = _resourceMgr.listAllUpAndEnabledHosts(type, clusterId, podId, dcId);
         }
-        
+
         s_logger.debug("Random Allocator found " + hosts.size() + "  hosts");
-        
+
         if (hosts.size() == 0) {
             return suitableHosts;
         }
@@ -93,12 +92,12 @@ public class RandomAllocator implements HostAllocator {
 
         Collections.shuffle(hosts);
         for (Host host : hosts) {
-        	if(suitableHosts.size() == returnUpTo){
-        		break;
-        	}
-        	
+            if(suitableHosts.size() == returnUpTo){
+                break;
+            }
+
             if (!avoid.shouldAvoid(host)) {
-            	suitableHosts.add(host);
+                suitableHosts.add(host);
             }else{
                 if (s_logger.isDebugEnabled()) {
                     s_logger.debug("Host name: " + host.getName() + ", hostId: "+ host.getId() +" is in avoid set, skipping this and trying other available hosts");
@@ -121,7 +120,7 @@ public class RandomAllocator implements HostAllocator {
     @Override
     public boolean configure(String name, Map<String, Object> params) {
         _name=name;
-        
+
         return true;
     }