You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2013/01/25 13:55:10 UTC

[5/50] git commit: CLOUDSTACK-355: create DB view for ServiceOfferingResponse to fix count for ListServiceOfferingsCmd.

CLOUDSTACK-355: create DB view for ServiceOfferingResponse to fix count
for ListServiceOfferingsCmd.


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/6e40c336
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/6e40c336
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/6e40c336

Branch: refs/heads/events-framework
Commit: 6e40c336287e2c68f763d10e80654d9151ac56b7
Parents: a4c413b
Author: Min Chen <mi...@citrix.com>
Authored: Mon Jan 21 15:07:35 2013 -0800
Committer: Min Chen <mi...@citrix.com>
Committed: Mon Jan 21 15:25:49 2013 -0800

----------------------------------------------------------------------
 api/src/com/cloud/server/ManagementService.java    |    7 -
 .../user/offering/ListServiceOfferingsCmd.java     |   17 +-
 .../org/apache/cloudstack/query/QueryService.java  |    4 +
 server/src/com/cloud/api/ApiDBUtils.java           |   13 +
 server/src/com/cloud/api/ApiResponseHelper.java    |   30 +--
 server/src/com/cloud/api/ApiServer.java            |    2 +
 .../src/com/cloud/api/query/QueryManagerImpl.java  |  154 +++++++
 .../com/cloud/api/query/ViewResponseHelper.java    |   10 +
 .../api/query/dao/ServiceOfferingJoinDao.java      |   30 ++
 .../api/query/dao/ServiceOfferingJoinDaoImpl.java  |   91 +++++
 .../cloud/api/query/vo/ServiceOfferingJoinVO.java  |  311 +++++++++++++++
 .../configuration/DefaultComponentLibrary.java     |    2 +
 .../src/com/cloud/server/ManagementServerImpl.java |  217 ----------
 setup/db/create-schema-view.sql                    |   33 ++-
 setup/db/db/schema-40to410.sql                     |   31 ++
 15 files changed, 686 insertions(+), 266 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/api/src/com/cloud/server/ManagementService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java
index 9935565..3bc7f93 100755
--- a/api/src/com/cloud/server/ManagementService.java
+++ b/api/src/com/cloud/server/ManagementService.java
@@ -110,13 +110,6 @@ public interface ManagementService {
      */
     Pair<List<? extends Configuration>, Integer> searchForConfigurations(ListCfgsByCmd c);
 
-    /**
-     * Searches for Service Offerings by the specified search criteria Can search by: "name"
-     *
-     * @param cmd
-     * @return List of ServiceOfferings
-     */
-    List<? extends ServiceOffering> searchForServiceOfferings(ListServiceOfferingsCmd cmd);
 
     /**
      * Searches for Clusters by the specified search criteria

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java b/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
index 9fad577..5f773d0 100644
--- a/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
@@ -16,9 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.offering;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.api.ApiConstants;
@@ -29,7 +26,6 @@ import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
-import com.cloud.offering.ServiceOffering;
 
 @APICommand(name = "listServiceOfferings", description="Lists all available service offerings.", responseObject=ServiceOfferingResponse.class)
 public class ListServiceOfferingsCmd extends BaseListCmd {
@@ -102,17 +98,10 @@ public class ListServiceOfferingsCmd extends BaseListCmd {
 
     @Override
     public void execute(){
-        List<? extends ServiceOffering> offerings = _mgr.searchForServiceOfferings(this);
-        ListResponse<ServiceOfferingResponse> response = new ListResponse<ServiceOfferingResponse>();
-        List<ServiceOfferingResponse> offeringResponses = new ArrayList<ServiceOfferingResponse>();
-        for (ServiceOffering offering : offerings) {
-            ServiceOfferingResponse offeringResponse = _responseGenerator.createServiceOfferingResponse(offering);
-            offeringResponse.setObjectName("serviceoffering");
-            offeringResponses.add(offeringResponse);
-        }
-
-        response.setResponses(offeringResponses);
+
+        ListResponse<ServiceOfferingResponse> response = _queryService.searchForServiceOfferings(this);
         response.setResponseName(getCommandName());
         this.setResponseObject(response);
+
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/api/src/org/apache/cloudstack/query/QueryService.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java
index f2b0d32..add9d23 100644
--- a/api/src/org/apache/cloudstack/query/QueryService.java
+++ b/api/src/org/apache/cloudstack/query/QueryService.java
@@ -27,6 +27,7 @@ import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
 import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
 import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
 import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
 import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
 import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
 import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
@@ -47,6 +48,7 @@ import org.apache.cloudstack.api.response.ProjectInvitationResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.ResourceTagResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
@@ -96,4 +98,6 @@ public interface QueryService {
     public ListResponse<AsyncJobResponse>  searchForAsyncJobs(ListAsyncJobsCmd cmd);
 
     public ListResponse<DiskOfferingResponse>  searchForDiskOfferings(ListDiskOfferingsCmd cmd);
+
+    public ListResponse<ServiceOfferingResponse>  searchForServiceOfferings(ListServiceOfferingsCmd cmd);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index 3f2f0bb..9b88664 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -36,6 +36,7 @@ import org.apache.cloudstack.api.response.ProjectInvitationResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.ResourceTagResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
@@ -52,6 +53,7 @@ import com.cloud.api.query.dao.ProjectInvitationJoinDao;
 import com.cloud.api.query.dao.ProjectJoinDao;
 import com.cloud.api.query.dao.ResourceTagJoinDao;
 import com.cloud.api.query.dao.SecurityGroupJoinDao;
+import com.cloud.api.query.dao.ServiceOfferingJoinDao;
 import com.cloud.api.query.dao.StoragePoolJoinDao;
 import com.cloud.api.query.dao.UserAccountJoinDao;
 import com.cloud.api.query.dao.UserVmJoinDao;
@@ -68,6 +70,7 @@ import com.cloud.api.query.vo.ProjectInvitationJoinVO;
 import com.cloud.api.query.vo.ProjectJoinVO;
 import com.cloud.api.query.vo.ResourceTagJoinVO;
 import com.cloud.api.query.vo.SecurityGroupJoinVO;
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
 import com.cloud.api.query.vo.StoragePoolJoinVO;
 import com.cloud.api.query.vo.UserAccountJoinVO;
 import com.cloud.api.query.vo.UserVmJoinVO;
@@ -338,6 +341,7 @@ public class ApiDBUtils {
     private static AccountJoinDao _accountJoinDao;
     private static AsyncJobJoinDao _jobJoinDao;
     private static DiskOfferingJoinDao _diskOfferingJoinDao;
+    private static ServiceOfferingJoinDao _srvOfferingJoinDao;
 
     private static PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
     private static PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@@ -443,6 +447,7 @@ public class ApiDBUtils {
         _snapshotPolicyDao = locator.getDao(SnapshotPolicyDao.class);
         _asyncJobDao = locator.getDao(AsyncJobDao.class);
         _diskOfferingJoinDao = locator.getDao(DiskOfferingJoinDao.class);
+        _srvOfferingJoinDao = locator.getDao(ServiceOfferingJoinDao.class);
 
         // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned
         _statsCollector = StatsCollector.getInstance();
@@ -1413,4 +1418,12 @@ public class ApiDBUtils {
    public static DiskOfferingJoinVO newDiskOfferingView(DiskOffering offering){
        return _diskOfferingJoinDao.newDiskOfferingView(offering);
    }
+
+   public static ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offering) {
+       return _srvOfferingJoinDao.newServiceOfferingResponse(offering);
+   }
+
+   public static ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering){
+       return _srvOfferingJoinDao.newServiceOfferingView(offering);
+   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 07646d8..1965f33 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -54,6 +54,7 @@ import com.cloud.api.query.vo.ProjectInvitationJoinVO;
 import com.cloud.api.query.vo.ProjectJoinVO;
 import com.cloud.api.query.vo.ResourceTagJoinVO;
 import com.cloud.api.query.vo.SecurityGroupJoinVO;
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
 import com.cloud.api.query.vo.StoragePoolJoinVO;
 import com.cloud.api.query.vo.UserAccountJoinVO;
 import com.cloud.api.query.vo.UserVmJoinVO;
@@ -342,33 +343,8 @@ public class ApiResponseHelper implements ResponseGenerator {
 
     @Override
     public ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering) {
-        ServiceOfferingResponse offeringResponse = new ServiceOfferingResponse();
-        offeringResponse.setId(offering.getUuid());
-        offeringResponse.setName(offering.getName());
-        offeringResponse.setIsSystemOffering(offering.getSystemUse());
-        offeringResponse.setDefaultUse(offering.getDefaultUse());
-        offeringResponse.setSystemVmType(offering.getSystemVmType());
-        offeringResponse.setDisplayText(offering.getDisplayText());
-        offeringResponse.setCpuNumber(offering.getCpu());
-        offeringResponse.setCpuSpeed(offering.getSpeed());
-        offeringResponse.setMemory(offering.getRamSize());
-        offeringResponse.setCreated(offering.getCreated());
-        offeringResponse.setStorageType(offering.getUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString());
-        offeringResponse.setOfferHa(offering.getOfferHA());
-        offeringResponse.setLimitCpuUse(offering.getLimitCpuUse());
-        offeringResponse.setTags(offering.getTags());
-        if (offering.getDomainId() != null) {
-            Domain domain = ApiDBUtils.findDomainById(offering.getDomainId());
-            if (domain != null) {
-                offeringResponse.setDomain(domain.getName());
-                offeringResponse.setDomainId(domain.getUuid());
-            }
-        }
-        offeringResponse.setNetworkRate(offering.getRateMbps());
-        offeringResponse.setHostTag(offering.getHostTag());
-        offeringResponse.setObjectName("serviceoffering");
-
-        return offeringResponse;
+        ServiceOfferingJoinVO vOffering = ApiDBUtils.newServiceOfferingView(offering);
+        return ApiDBUtils.newServiceOfferingResponse(vOffering);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 19c8851..ad2a12f 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -96,6 +96,7 @@ import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
 import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
 import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
 import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
 import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
 import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
 import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
@@ -516,6 +517,7 @@ public class ApiServer implements HttpRequestHandler {
                     && !(cmdObj instanceof ListAccountsCmd)
                     && !(cmdObj instanceof ListStoragePoolsCmd)
                     && !(cmdObj instanceof ListDiskOfferingsCmd)
+                    && !(cmdObj instanceof ListServiceOfferingsCmd)
                     ) {
                 buildAsyncListResponse((BaseListCmd) cmdObj, caller);
             }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
index c38603f..ee47296 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -33,6 +33,7 @@ import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
 import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
 import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
 import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
 import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
 import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
 import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
@@ -53,6 +54,7 @@ import org.apache.cloudstack.api.response.ProjectInvitationResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.ResourceTagResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
@@ -71,6 +73,7 @@ import com.cloud.api.query.dao.ProjectInvitationJoinDao;
 import com.cloud.api.query.dao.ProjectJoinDao;
 import com.cloud.api.query.dao.ResourceTagJoinDao;
 import com.cloud.api.query.dao.SecurityGroupJoinDao;
+import com.cloud.api.query.dao.ServiceOfferingJoinDao;
 import com.cloud.api.query.dao.StoragePoolJoinDao;
 import com.cloud.api.query.dao.UserAccountJoinDao;
 import com.cloud.api.query.dao.UserVmJoinDao;
@@ -87,6 +90,7 @@ import com.cloud.api.query.vo.ProjectInvitationJoinVO;
 import com.cloud.api.query.vo.ProjectJoinVO;
 import com.cloud.api.query.vo.ResourceTagJoinVO;
 import com.cloud.api.query.vo.SecurityGroupJoinVO;
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
 import com.cloud.api.query.vo.StoragePoolJoinVO;
 import com.cloud.api.query.vo.UserAccountJoinVO;
 import com.cloud.api.query.vo.UserVmJoinVO;
@@ -110,6 +114,8 @@ import com.cloud.projects.ProjectManager;
 import com.cloud.projects.dao.ProjectAccountDao;
 import com.cloud.projects.dao.ProjectDao;
 import com.cloud.server.Criteria;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.StoragePoolVO;
@@ -222,6 +228,12 @@ public class QueryManagerImpl implements QueryService, Manager {
     private DiskOfferingJoinDao _diskOfferingJoinDao;
 
     @Inject
+    private ServiceOfferingJoinDao _srvOfferingJoinDao;
+
+    @Inject
+    private ServiceOfferingDao _srvOfferingDao;
+
+    @Inject
     private HighAvailabilityManager _haMgr;
 
     @Override
@@ -2033,6 +2045,148 @@ public class QueryManagerImpl implements QueryService, Manager {
     }
 
 
+
+    @Override
+    public ListResponse<ServiceOfferingResponse> searchForServiceOfferings(ListServiceOfferingsCmd cmd) {
+        Pair<List<ServiceOfferingJoinVO>, Integer> result = searchForServiceOfferingsInternal(cmd);
+        ListResponse<ServiceOfferingResponse> response = new ListResponse<ServiceOfferingResponse>();
+        List<ServiceOfferingResponse> offeringResponses = ViewResponseHelper.createServiceOfferingResponse(result.first().toArray(new ServiceOfferingJoinVO[result.first().size()]));
+        response.setResponses(offeringResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInternal(ListServiceOfferingsCmd cmd) {
+        // Note
+        // The list method for offerings is being modified in accordance with
+        // discussion with Will/Kevin
+        // For now, we will be listing the following based on the usertype
+        // 1. For root, we will list all offerings
+        // 2. For domainAdmin and regular users, we will list everything in
+        // their domains+parent domains ... all the way
+        // till
+        // root
+        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
+        isAscending = (isAscending == null ? true : isAscending);
+        Filter searchFilter = new Filter(ServiceOfferingJoinVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
+
+        Account caller = UserContext.current().getCaller();
+        Object name = cmd.getServiceOfferingName();
+        Object id = cmd.getId();
+        Object keyword = cmd.getKeyword();
+        Long vmId = cmd.getVirtualMachineId();
+        Long domainId = cmd.getDomainId();
+        Boolean isSystem = cmd.getIsSystem();
+        String vmTypeStr = cmd.getSystemVmType();
+
+        if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && isSystem) {
+            throw new InvalidParameterValueException("Only ROOT admins can access system's offering");
+        }
+
+        // Keeping this logic consistent with domain specific zones
+        // if a domainId is provided, we just return the so associated with this
+        // domain
+        if (domainId != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            // check if the user's domain == so's domain || user's domain is a
+            // child of so's domain
+            if (!isPermissible(caller.getDomainId(), domainId)) {
+                throw new PermissionDeniedException("The account:" + caller.getAccountName()
+                        + " does not fall in the same domain hierarchy as the service offering");
+            }
+        }
+
+        boolean includePublicOfferings = false;
+        if ((caller.getType() == Account.ACCOUNT_TYPE_NORMAL || caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
+                || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+            // For non-root users
+            if (isSystem) {
+                throw new InvalidParameterValueException("Only root admins can access system's offering");
+            }
+            // find all domain Id up to root domain for this account
+            List<Long> domainIds = new ArrayList<Long>();
+            DomainVO domainRecord = _domainDao.findById(caller.getDomainId());
+            if ( domainRecord == null ){
+                s_logger.error("Could not find the domainId for account:" + caller.getAccountName());
+                throw new CloudAuthenticationException("Could not find the domainId for account:" + caller.getAccountName());
+            }
+            domainIds.add(domainRecord.getId());
+            while (domainRecord.getParent() != null ){
+                domainRecord = _domainDao.findById(domainRecord.getParent());
+                domainIds.add(domainRecord.getId());
+            }
+            sc.addAnd("domainIdIn", SearchCriteria.Op.IN, domainIds);
+
+            // include also public offering if no keyword, name and id specified
+            if ( keyword == null && name == null && id == null ){
+                includePublicOfferings = true;
+            }
+        }
+        else {
+            // for root users
+            if (caller.getDomainId() != 1 && isSystem) { // NON ROOT admin
+                throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering");
+            }
+            if (domainId != null) {
+                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
+            }
+        }
+
+        if (keyword != null) {
+            SearchCriteria<ServiceOfferingJoinVO> ssc = _srvOfferingJoinDao.createSearchCriteria();
+            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        } else if (vmId != null) {
+            UserVmVO vmInstance = _userVmDao.findById(vmId);
+            if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
+                InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id");
+                ex.addProxyObject(vmInstance, vmId, "vmId");
+                throw ex;
+            }
+
+            _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+            ServiceOfferingVO offering = _srvOfferingDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId());
+            sc.addAnd("id", SearchCriteria.Op.NEQ, offering.getId());
+
+            // Only return offerings with the same Guest IP type and storage
+            // pool preference
+            // sc.addAnd("guestIpType", SearchCriteria.Op.EQ,
+            // offering.getGuestIpType());
+            sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, offering.getUseLocalStorage());
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (isSystem != null) {
+            sc.addAnd("systemUse", SearchCriteria.Op.EQ, isSystem);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
+        }
+
+        if (vmTypeStr != null) {
+            sc.addAnd("vm_type", SearchCriteria.Op.EQ, vmTypeStr);
+        }
+
+        if (includePublicOfferings){
+            SearchCriteria<ServiceOfferingJoinVO> spc = _srvOfferingJoinDao.createSearchCriteria();
+            spc.addAnd("domainId", SearchCriteria.Op.NULL);
+            spc.addAnd("systemUse", SearchCriteria.Op.EQ, false);
+            sc.addOr("systemUse", SearchCriteria.Op.SC, spc);
+        }
+
+        return _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
+
+    }
+
+
+
+
     // This method is used for permissions check for both disk and service
     // offerings
     private boolean isPermissible(Long accountDomainId, Long offeringDomainId) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/query/ViewResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java
index 9c761d4..dfccdce 100644
--- a/server/src/com/cloud/api/query/ViewResponseHelper.java
+++ b/server/src/com/cloud/api/query/ViewResponseHelper.java
@@ -35,6 +35,7 @@ import org.apache.cloudstack.api.response.ProjectInvitationResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.ResourceTagResponse;
 import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
@@ -54,6 +55,7 @@ import com.cloud.api.query.vo.ProjectInvitationJoinVO;
 import com.cloud.api.query.vo.ProjectJoinVO;
 import com.cloud.api.query.vo.ResourceTagJoinVO;
 import com.cloud.api.query.vo.SecurityGroupJoinVO;
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
 import com.cloud.api.query.vo.StoragePoolJoinVO;
 import com.cloud.api.query.vo.UserAccountJoinVO;
 import com.cloud.api.query.vo.UserVmJoinVO;
@@ -284,4 +286,12 @@ public class ViewResponseHelper {
         }
         return respList;
     }
+
+    public static List<ServiceOfferingResponse> createServiceOfferingResponse(ServiceOfferingJoinVO... offerings) {
+        List<ServiceOfferingResponse> respList = new ArrayList<ServiceOfferingResponse>();
+        for (ServiceOfferingJoinVO vt : offerings){
+            respList.add(ApiDBUtils.newServiceOfferingResponse(vt));
+        }
+        return respList;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDao.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
new file mode 100644
index 0000000..a797125
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api.query.dao;
+
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.utils.db.GenericDao;
+
+public interface ServiceOfferingJoinDao extends GenericDao<ServiceOfferingJoinVO, Long> {
+
+    ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offering);
+
+    ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
new file mode 100644
index 0000000..8827c48
--- /dev/null
+++ b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
@@ -0,0 +1,91 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api.query.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+
+import com.cloud.offering.ServiceOffering;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+
+@Local(value={ServiceOfferingJoinDao.class})
+public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJoinVO, Long> implements ServiceOfferingJoinDao {
+    public static final Logger s_logger = Logger.getLogger(ServiceOfferingJoinDaoImpl.class);
+
+
+    private SearchBuilder<ServiceOfferingJoinVO> sofIdSearch;
+
+     protected ServiceOfferingJoinDaoImpl() {
+
+        sofIdSearch = createSearchBuilder();
+        sofIdSearch.and("id", sofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        sofIdSearch.done();
+
+        this._count = "select count(distinct id) from service_offering_view WHERE ";
+    }
+
+
+
+    @Override
+    public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offering) {
+
+        ServiceOfferingResponse offeringResponse = new ServiceOfferingResponse();
+        offeringResponse.setId(offering.getUuid());
+        offeringResponse.setName(offering.getName());
+        offeringResponse.setIsSystemOffering(offering.isSystemUse());
+        offeringResponse.setDefaultUse(offering.isDefaultUse());
+        offeringResponse.setSystemVmType(offering.getSystemVmType());
+        offeringResponse.setDisplayText(offering.getDisplayText());
+        offeringResponse.setCpuNumber(offering.getCpu());
+        offeringResponse.setCpuSpeed(offering.getSpeed());
+        offeringResponse.setMemory(offering.getRamSize());
+        offeringResponse.setCreated(offering.getCreated());
+        offeringResponse.setStorageType(offering.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString()
+                : ServiceOffering.StorageType.shared.toString());
+        offeringResponse.setOfferHa(offering.isOfferHA());
+        offeringResponse.setLimitCpuUse(offering.isLimitCpuUse());
+        offeringResponse.setTags(offering.getTags());
+        offeringResponse.setDomain(offering.getDomainName());
+        offeringResponse.setDomainId(offering.getDomainUuid());
+        offeringResponse.setNetworkRate(offering.getRateMbps());
+        offeringResponse.setHostTag(offering.getHostTag());
+        offeringResponse.setObjectName("serviceoffering");
+
+        return offeringResponse;
+    }
+
+
+    @Override
+    public ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering) {
+        SearchCriteria<ServiceOfferingJoinVO> sc = sofIdSearch.create();
+        sc.setParameters("id", offering.getId());
+        List<ServiceOfferingJoinVO> offerings = searchIncludingRemoved(sc, null, null, false);
+        assert offerings != null && offerings.size() == 1 : "No service offering found for offering id " + offering.getId();
+        return offerings.get(0);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
new file mode 100644
index 0000000..fe4a165
--- /dev/null
+++ b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
@@ -0,0 +1,311 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.api.query.vo;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.utils.db.GenericDao;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+@Entity
+@Table(name="service_offering_view")
+public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentity, Identity {
+
+    @Id
+    @Column(name="id", updatable=false, nullable = false)
+    private long id;
+
+    @Column(name="uuid")
+    private String uuid;
+
+    @Column(name="name")
+    private String name;
+
+    @Column(name="display_text")
+    private String displayText;
+
+    @Column(name="tags", length=4096)
+    String tags;
+
+    @Column(name="use_local_storage")
+    private boolean useLocalStorage;
+
+    @Column(name="system_use")
+    private boolean systemUse;
+
+    @Column(name="cpu")
+    private int cpu;
+
+    @Column(name="speed")
+    private int speed;
+
+    @Column(name="ram_size")
+    private int ramSize;
+
+    @Column(name="nw_rate")
+    private Integer rateMbps;
+
+    @Column(name="mc_rate")
+    private Integer multicastRateMbps;
+
+    @Column(name="ha_enabled")
+    private boolean offerHA;
+
+    @Column(name="limit_cpu_use")
+    private boolean limitCpuUse;
+
+    @Column(name="host_tag")
+    private String hostTag;
+
+    @Column(name="default_use")
+    private boolean default_use;
+
+    @Column(name="vm_type")
+    private String vm_type;
+
+    @Column(name="sort_key")
+    int sortKey;
+
+
+    @Column(name=GenericDao.CREATED_COLUMN)
+    private Date created;
+
+    @Column(name=GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name="domain_id")
+    private long domainId;
+
+    @Column(name="domain_uuid")
+    private String domainUuid;
+
+    @Column(name="domain_name")
+    private String domainName = null;
+
+    @Column(name="domain_path")
+    private String domainPath = null;
+
+
+    public ServiceOfferingJoinVO() {
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+
+    public String getTags() {
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+    public boolean isUseLocalStorage() {
+        return useLocalStorage;
+    }
+
+    public void setUseLocalStorage(boolean useLocalStorage) {
+        this.useLocalStorage = useLocalStorage;
+    }
+
+    public boolean isSystemUse() {
+        return systemUse;
+    }
+
+    public void setSystemUse(boolean systemUse) {
+        this.systemUse = systemUse;
+    }
+
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    public long getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(long domainId) {
+        this.domainId = domainId;
+    }
+
+    public String getDomainUuid() {
+        return domainUuid;
+    }
+
+    public void setDomainUuid(String domainUuid) {
+        this.domainUuid = domainUuid;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+    public String getDomainPath() {
+        return domainPath;
+    }
+
+    public void setDomainPath(String domainPath) {
+        this.domainPath = domainPath;
+    }
+
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    public void setSortKey(int sortKey) {
+        this.sortKey = sortKey;
+    }
+
+    public int getCpu() {
+        return cpu;
+    }
+
+    public void setCpu(int cpu) {
+        this.cpu = cpu;
+    }
+
+    public int getSpeed() {
+        return speed;
+    }
+
+    public void setSpeed(int speed) {
+        this.speed = speed;
+    }
+
+    public int getRamSize() {
+        return ramSize;
+    }
+
+    public void setRamSize(int ramSize) {
+        this.ramSize = ramSize;
+    }
+
+    public Integer getRateMbps() {
+        return rateMbps;
+    }
+
+    public void setRateMbps(Integer rateMbps) {
+        this.rateMbps = rateMbps;
+    }
+
+    public Integer getMulticastRateMbps() {
+        return multicastRateMbps;
+    }
+
+    public void setMulticastRateMbps(Integer multicastRateMbps) {
+        this.multicastRateMbps = multicastRateMbps;
+    }
+
+    public boolean isOfferHA() {
+        return offerHA;
+    }
+
+    public void setOfferHA(boolean offerHA) {
+        this.offerHA = offerHA;
+    }
+
+    public boolean isLimitCpuUse() {
+        return limitCpuUse;
+    }
+
+    public void setLimitCpuUse(boolean limitCpuUse) {
+        this.limitCpuUse = limitCpuUse;
+    }
+
+    public String getHostTag() {
+        return hostTag;
+    }
+
+    public void setHostTag(String hostTag) {
+        this.hostTag = hostTag;
+    }
+
+    public boolean isDefaultUse() {
+        return default_use;
+    }
+
+    public void setDefaultUse(boolean default_use) {
+        this.default_use = default_use;
+    }
+
+    public String getSystemVmType() {
+        return vm_type;
+    }
+
+    public void setSystemVmType(String vm_type) {
+        this.vm_type = vm_type;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/configuration/DefaultComponentLibrary.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
index 5a1b002..9652586 100755
--- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java
+++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
@@ -28,6 +28,7 @@ import com.cloud.api.query.QueryManagerImpl;
 import com.cloud.api.query.dao.AccountJoinDaoImpl;
 import com.cloud.api.query.dao.AsyncJobJoinDaoImpl;
 import com.cloud.api.query.dao.DiskOfferingJoinDaoImpl;
+import com.cloud.api.query.dao.ServiceOfferingJoinDaoImpl;
 import com.cloud.api.query.dao.DomainRouterJoinDaoImpl;
 import com.cloud.api.query.dao.InstanceGroupJoinDaoImpl;
 import com.cloud.api.query.dao.ProjectAccountJoinDaoImpl;
@@ -394,6 +395,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
         addDao("AsyncJobJoinDao", AsyncJobJoinDaoImpl.class);
         addDao("StoragePoolJoinDao", StoragePoolJoinDaoImpl.class);
         addDao("DiskOfferingJoinDao", DiskOfferingJoinDaoImpl.class);
+        addDao("ServiceOfferingJoinDao", ServiceOfferingJoinDaoImpl.class);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 0684440..8182421 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -54,7 +54,6 @@ import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd;
 import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd;
 import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
 import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
-import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
 import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd;
 import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd;
 import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
@@ -132,7 +131,6 @@ import com.cloud.event.EventTypes;
 import com.cloud.event.EventUtils;
 import com.cloud.event.EventVO;
 import com.cloud.event.dao.EventDao;
-import com.cloud.exception.CloudAuthenticationException;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.OperationTimedoutException;
@@ -607,221 +605,6 @@ public class ManagementServerImpl implements ManagementServer {
         return cal.getTime();
     }
 
-    // This method is used for permissions check for both disk and service
-    // offerings
-    private boolean isPermissible(Long accountDomainId, Long offeringDomainId) {
-
-        if (accountDomainId == offeringDomainId) {
-            return true; // account and service offering in same domain
-        }
-
-        DomainVO domainRecord = _domainDao.findById(accountDomainId);
-
-        if (domainRecord != null) {
-            while (true) {
-                if (domainRecord.getId() == offeringDomainId) {
-                    return true;
-                }
-
-                // try and move on to the next domain
-                if (domainRecord.getParent() != null) {
-                    domainRecord = _domainDao.findById(domainRecord.getParent());
-                } else {
-                    break;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public List<ServiceOfferingVO> searchForServiceOfferings(ListServiceOfferingsCmd cmd) {
-
-        // Note
-        // The list method for offerings is being modified in accordance with
-        // discussion with Will/Kevin
-        // For now, we will be listing the following based on the usertype
-        // 1. For root, we will list all offerings
-        // 2. For domainAdmin and regular users, we will list everything in
-        // their domains+parent domains ... all the way
-        // till
-        // root
-        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
-        isAscending = (isAscending == null ? true : isAscending);
-        Filter searchFilter = new Filter(ServiceOfferingVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchCriteria<ServiceOfferingVO> sc = _offeringsDao.createSearchCriteria();
-
-        Account caller = UserContext.current().getCaller();
-        Object name = cmd.getServiceOfferingName();
-        Object id = cmd.getId();
-        Object keyword = cmd.getKeyword();
-        Long vmId = cmd.getVirtualMachineId();
-        Long domainId = cmd.getDomainId();
-        Boolean isSystem = cmd.getIsSystem();
-        String vmTypeStr = cmd.getSystemVmType();
-
-        if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && isSystem) {
-            throw new InvalidParameterValueException("Only ROOT admins can access system's offering");
-        }
-
-        // Keeping this logic consistent with domain specific zones
-        // if a domainId is provided, we just return the so associated with this
-        // domain
-        if (domainId != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            // check if the user's domain == so's domain || user's domain is a
-            // child of so's domain
-            if (!isPermissible(caller.getDomainId(), domainId)) {
-                throw new PermissionDeniedException("The account:" + caller.getAccountName()
-                        + " does not fall in the same domain hierarchy as the service offering");
-            }
-        }
-
-        // For non-root users
-        if ((caller.getType() == Account.ACCOUNT_TYPE_NORMAL || caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
-                || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-            if (isSystem) {
-                throw new InvalidParameterValueException("Only root admins can access system's offering");
-            }
-            return searchServiceOfferingsInternal(caller, name, id, vmId, keyword, searchFilter);
-        }
-
-        // for root users, the existing flow
-        if (caller.getDomainId() != 1 && isSystem) { // NON ROOT admin
-            throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering");
-        }
-
-        if (keyword != null) {
-            SearchCriteria<ServiceOfferingVO> ssc = _offeringsDao.createSearchCriteria();
-            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        } else if (vmId != null) {
-            UserVmVO vmInstance = _userVmDao.findById(vmId);
-            if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
-                InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id");
-                ex.addProxyObject(vmInstance, vmId, "vmId");
-                throw ex;
-            }
-
-            _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-            ServiceOfferingVO offering = _offeringsDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId());
-            sc.addAnd("id", SearchCriteria.Op.NEQ, offering.getId());
-
-            // Only return offerings with the same Guest IP type and storage
-            // pool preference
-            // sc.addAnd("guestIpType", SearchCriteria.Op.EQ,
-            // offering.getGuestIpType());
-            sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, offering.getUseLocalStorage());
-        }
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (isSystem != null) {
-            sc.addAnd("systemUse", SearchCriteria.Op.EQ, isSystem);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
-        }
-
-        if (domainId != null) {
-            sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
-        }
-
-        if (vmTypeStr != null) {
-            sc.addAnd("vm_type", SearchCriteria.Op.EQ, vmTypeStr);
-        }
-
-        sc.addAnd("removed", SearchCriteria.Op.NULL);
-        return _offeringsDao.search(sc, searchFilter);
-
-    }
-
-    private List<ServiceOfferingVO> searchServiceOfferingsInternal(Account caller, Object name, Object id, Long vmId, Object keyword,
-            Filter searchFilter) {
-
-        // it was decided to return all offerings for the user's domain, and
-        // everything above till root (for normal user
-        // or
-        // domain admin)
-        // list all offerings belonging to this domain, and all of its parents
-        // check the parent, if not null, add offerings for that parent to list
-        List<ServiceOfferingVO> sol = new ArrayList<ServiceOfferingVO>();
-        DomainVO domainRecord = _domainDao.findById(caller.getDomainId());
-        boolean includePublicOfferings = true;
-        if (domainRecord != null) {
-            while (true) {
-                if (id != null) {
-                    ServiceOfferingVO so = _offeringsDao.findById((Long) id);
-                    if (so != null) {
-                        sol.add(so);
-                    }
-                    return sol;
-                }
-
-                SearchCriteria<ServiceOfferingVO> sc = _offeringsDao.createSearchCriteria();
-
-                if (keyword != null) {
-                    includePublicOfferings = false;
-                    SearchCriteria<ServiceOfferingVO> ssc = _offeringsDao.createSearchCriteria();
-                    ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-                    ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-                    sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-                } else if (vmId != null) {
-                    UserVmVO vmInstance = _userVmDao.findById(vmId);
-                    if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
-                        InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-                        ex.addProxyObject(vmInstance, vmId, "vmId");
-                        throw ex;
-                    }
-
-                    _accountMgr.checkAccess(caller, null, false, vmInstance);
-
-                    ServiceOfferingVO offering = _offeringsDao.findById(vmInstance.getServiceOfferingId());
-                    sc.addAnd("id", SearchCriteria.Op.NEQ, offering.getId());
-
-                    sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, offering.getUseLocalStorage());
-                }
-
-                if (name != null) {
-                    includePublicOfferings = false;
-                    sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
-                }
-                sc.addAnd("systemUse", SearchCriteria.Op.EQ, false);
-
-                // for this domain
-                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainRecord.getId());
-
-                // don't return removed service offerings
-                sc.addAnd("removed", SearchCriteria.Op.NULL);
-
-                // search and add for this domain
-                sol.addAll(_offeringsDao.search(sc, searchFilter));
-
-                // try and move on to the next domain
-                if (domainRecord.getParent() != null) {
-                    domainRecord = _domainDao.findById(domainRecord.getParent());
-                } else {
-                    break;// now we got all the offerings for this user/dom adm
-                }
-            }
-        } else {
-            s_logger.error("Could not find the domainId for account:" + caller.getAccountName());
-            throw new CloudAuthenticationException("Could not find the domainId for account:" + caller.getAccountName());
-        }
-
-        // add all the public offerings to the sol list before returning
-        if (includePublicOfferings) {
-            sol.addAll(_offeringsDao.findPublicServiceOfferings());
-        }
-
-        return sol;
-    }
 
     @Override
     public List<? extends Cluster> searchForClusters(long zoneId, Long startIndex, Long pageSizeVal, String hypervisorType) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/setup/db/create-schema-view.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema-view.sql b/setup/db/create-schema-view.sql
index 63f5998..495b6c5 100644
--- a/setup/db/create-schema-view.sql
+++ b/setup/db/create-schema-view.sql
@@ -841,4 +841,35 @@ domain.uuid domain_uuid,
 domain.name domain_name, 
 domain.path domain_path
 from disk_offering 
-left join domain on disk_offering.domain_id=domain.id;
\ No newline at end of file
+left join domain on disk_offering.domain_id=domain.id;
+
+DROP VIEW IF EXISTS `cloud`.`service_offering_view`;
+CREATE VIEW service_offering_view AS
+select 
+service_offering.id,
+disk_offering.uuid,
+disk_offering.name,
+disk_offering.display_text,
+disk_offering.created,
+disk_offering.tags,
+disk_offering.removed,
+disk_offering.use_local_storage,
+disk_offering.system_use,
+service_offering.cpu,
+service_offering.speed,
+service_offering.ram_size,
+service_offering.nw_rate,
+service_offering.mc_rate,
+service_offering.ha_enabled,
+service_offering.limit_cpu_use,
+service_offering.host_tag,
+service_offering.default_use,
+service_offering.vm_type,
+service_offering.sort_key,
+domain.id domain_id, 
+domain.uuid domain_uuid,
+domain.name domain_name, 
+domain.path domain_path
+from service_offering 
+inner join disk_offering on service_offering.id = disk_offering.id
+left join domain on disk_offering.domain_id=domain.id;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e40c336/setup/db/db/schema-40to410.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql
index 9513b20..79b7f8f 100644
--- a/setup/db/db/schema-40to410.sql
+++ b/setup/db/db/schema-40to410.sql
@@ -968,5 +968,36 @@ domain.path domain_path
 from disk_offering 
 left join domain on disk_offering.domain_id=domain.id;
 
+DROP VIEW IF EXISTS `cloud`.`service_offering_view`;
+CREATE VIEW service_offering_view AS
+select 
+service_offering.id,
+disk_offering.uuid,
+disk_offering.name,
+disk_offering.display_text,
+disk_offering.created,
+disk_offering.tags,
+disk_offering.removed,
+disk_offering.use_local_storage,
+disk_offering.system_use,
+service_offering.cpu,
+service_offering.speed,
+service_offering.ram_size,
+service_offering.nw_rate,
+service_offering.mc_rate,
+service_offering.ha_enabled,
+service_offering.limit_cpu_use,
+service_offering.host_tag,
+service_offering.default_use,
+service_offering.vm_type,
+service_offering.sort_key,
+domain.id domain_id, 
+domain.uuid domain_uuid,
+domain.name domain_name, 
+domain.path domain_path
+from service_offering 
+inner join disk_offering on service_offering.id = disk_offering.id
+left join domain on disk_offering.domain_id=domain.id;
+
 
 INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'direct.agent.pool.size', '500', 'Default size for DirectAgentPool');