/** * Abiquo community edition * cloud management application for hybrid clouds * Copyright (C) 2008-2010 - Abiquo Holdings S.L. * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC * LICENSE as published by the Free Software Foundation under * version 3 of the License * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * LESSER GENERAL PUBLIC LICENSE v.3 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package com.abiquo.api.resources; import java.net.URLDecoder; import java.util.Collection; import java.util.List; import javax.validation.constraints.Min; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; import org.apache.wink.common.annotations.Parent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import com.abiquo.api.exceptions.APIError; import com.abiquo.api.exceptions.InternalServerErrorException; import com.abiquo.api.resources.cloud.IpAddressesResource; import com.abiquo.api.resources.cloud.VirtualApplianceResource; import com.abiquo.api.resources.cloud.VirtualDatacenterResource; import com.abiquo.api.resources.cloud.VirtualMachineResource; import com.abiquo.api.services.EnterpriseService; import com.abiquo.api.services.NetworkService; import com.abiquo.api.services.UserService; import com.abiquo.api.services.appslibrary.VirtualMachineTemplateService; import com.abiquo.api.services.cloud.VirtualApplianceService; import com.abiquo.api.services.cloud.VirtualDatacenterService; import com.abiquo.api.spring.security.SecurityService; import com.abiquo.api.util.IRESTBuilder; import com.abiquo.model.enumerator.Privileges; import com.abiquo.server.core.cloud.NodeVirtualImage; import com.abiquo.server.core.cloud.VirtualAppliance; import com.abiquo.server.core.cloud.VirtualApplianceDto; import com.abiquo.server.core.cloud.VirtualAppliancesDto; import com.abiquo.server.core.cloud.VirtualDatacenter; import com.abiquo.server.core.cloud.VirtualDatacenterDto; import com.abiquo.server.core.cloud.VirtualDatacentersDto; import com.abiquo.server.core.cloud.VirtualMachine; import com.abiquo.server.core.cloud.VirtualMachinesDto; import com.abiquo.server.core.enterprise.Enterprise; import com.abiquo.server.core.enterprise.EnterpriseDto; import com.abiquo.server.core.enterprise.User; import com.abiquo.server.core.infrastructure.network.IpPoolManagement; import com.abiquo.server.core.infrastructure.network.IpsPoolManagementDto; import com.abiquo.server.core.task.Task; import com.abiquo.server.core.task.TasksDto; import com.abiquo.server.core.util.FilterOptions; import com.abiquo.server.core.util.PagedList; @Parent(EnterprisesResource.class) @Path(EnterpriseResource.ENTERPRISE_PARAM) @Controller public class EnterpriseResource extends AbstractResource { public static final String ENTERPRISE = "enterprise"; // enterprise as query param public static final String ENTERPRISE_AS_PARAM = "identerprise"; public static final String ENTERPRISE_PARAM = "{" + ENTERPRISE + "}"; public static final String ENTERPRISE_ACTION_GET_IPS_PATH = "action/ips"; public static final String ENTERPRISE_ACTION_GET_ICONS_PATH = "action/icons"; public static final String ENTERPRISE_ACTION_GET_VIRTUALMACHINES_PATH = "action/virtualmachines"; public static final String ENTERPRISE_ACTION_GET_VIRTUALDATACENTERS_PATH = "action/virtualdatacenters"; public static final String ENTERPRISE_ACTION_GET_VIRTUALAPPLIANCES_PATH = "action/virtualappliances"; protected static final Logger LOGGER = LoggerFactory.getLogger(EnterpriseResource.class); public static final String ENTERPRISE1 = "enterprise1"; public static final String ENTERPRISE2 = "enterprise2"; @Autowired protected EnterpriseService service; @Autowired private NetworkService netService; @Autowired private VirtualDatacenterService vdcService; @Autowired private VirtualApplianceService vappService; @Autowired private VirtualMachineTemplateService vmtService; @Context protected UriInfo uriInfo; @Autowired private UserService userService; @Autowired private SecurityService securityService; /** * Returns an enterprise. * * @title Retrieve an Enterprise * @param enterpriseId identifier of an enterprise * @param restBuilder a Context-injected object to create the links of the Dto * @return an {EntepriseDto} object with the requested enterprise * @throws Exception */ @GET @Produces(EnterpriseDto.MEDIA_TYPE) public EnterpriseDto getEnterprise(@PathParam(ENTERPRISE) final Integer enterpriseId, @Context final IRESTBuilder restBuilder) throws Exception { if (!securityService.hasPrivilege(Privileges.USERS_MANAGE_OTHER_ENTERPRISES)) { User currentUser = userService.getCurrentUser(); if (currentUser.getEnterprise().getId().equals(enterpriseId)) { Enterprise enterprise = service.getEnterprise(enterpriseId); return createTransferObject(enterprise, restBuilder); } // We need to return the enterprise of the external VLAN to edit it, // and for that wee need to have DC_ENUMERATE privilege. else if (securityService.hasPrivilege(Privileges.PHYS_DC_ENUMERATE)) { Enterprise enterprise = service.getEnterprise(enterpriseId); return createTransferObject(enterprise, restBuilder); } else { // throws access denied exception securityService.requirePrivilege(Privileges.USERS_MANAGE_OTHER_ENTERPRISES); } } Enterprise enterprise = service.getEnterprise(enterpriseId); return createTransferObject(enterprise, restBuilder); } /** * Modifies an enterprise * * @title Update an existing enteprise * @param enterprise enterprise to modify * @param enterpriseId identifier of the enterprise * @param restBuilder a Context-injected object to create the links of the Dto * @return an {EnterpriseDto} object with the modified enterprise * @throws Exception */ @PUT @Produces(EnterpriseDto.MEDIA_TYPE) public EnterpriseDto modifyEnterprise(final EnterpriseDto enterprise, @PathParam(ENTERPRISE) final Integer enterpriseId, @Context final IRESTBuilder restBuilder) throws Exception { Enterprise e = service.modifyEnterprise(enterpriseId, enterprise); return createTransferObject(e, restBuilder); } /** * Deletes an enteprise. * * @title Delete an existing Enterprise * @param enterpriseId identifier of the enterprise */ @DELETE public void deleteEnterprise(@PathParam(ENTERPRISE) final Integer enterpriseId) { service.removeEnterprise(enterpriseId); } /** * Returns all ips from an enterprise * * @title Retrieve the list of private IPs created by an Enterprise * @param id identifier of the enterprise * @param startwith * @param orderBy * @param filter * @param limit * @param desc_or_asc * @param restBuilder a Context-injected object to create the links of the Dto * @return an {IpsPoolManagementDto} with all ips from an enterprise * @throws Exception */ @SuppressWarnings("unchecked") @GET @Path(EnterpriseResource.ENTERPRISE_ACTION_GET_IPS_PATH) @Produces(IpsPoolManagementDto.MEDIA_TYPE) public IpsPoolManagementDto getIPsByEnterprise(@PathParam(ENTERPRISE) @Min(0) final Integer id, @QueryParam(START_WITH) @DefaultValue("0") @Min(0) final Integer startwith, @QueryParam(BY) @DefaultValue("ip") final String orderBy, @QueryParam(FILTER) @DefaultValue("") final String filter, @QueryParam(LIMIT) @DefaultValue(DEFAULT_PAGE_LENGTH_STRING) @Min(1) final Integer limit, @QueryParam(ASC) @DefaultValue("true") final Boolean desc_or_asc, @Context final IRESTBuilder restBuilder) throws Exception { // Set query Params by default if they are not informed String filterwith = URLDecoder.decode(filter, "UTF-8"); List<IpPoolManagement> all = netService.getListIpPoolManagementByEnterprise(id, startwith, limit, filterwith, orderBy, desc_or_asc); if (all == null) { LOGGER.error("Unexpected null value getting the list of ip pools by enterprise."); throw new InternalServerErrorException(APIError.INTERNAL_SERVER_ERROR); } IpsPoolManagementDto ips = new IpsPoolManagementDto(); for (IpPoolManagement ip : all) { ips.add(IpAddressesResource.createTransferObject(ip, restBuilder)); } ips.setTotalSize(((PagedList) all).getTotalResults()); ips.addLinks(restBuilder.buildPaggingLinks(uriInfo.getAbsolutePath().toString(), (PagedList) all)); return ips; } /** * Retrieves the list Of Virtual machines defined into an enterprise. * * @title Retrieve a list of virtual machines by an Enterprise * @param enterpriseId identifier of the enterprise * @param restBuilder {@linnk IRESTBuilder} object injected by context * @return the {@link VirtualMachinesDto} object. A {@link VirtualMachineDto} wrapper. * @throws Exception */ @GET @Path(EnterpriseResource.ENTERPRISE_ACTION_GET_VIRTUALMACHINES_PATH) @Produces(VirtualMachinesDto.MEDIA_TYPE) public VirtualMachinesDto getVirtualMachines( @PathParam(EnterpriseResource.ENTERPRISE) final Integer enterpriseId, @Context final IRESTBuilder restBuilder) throws Exception { Enterprise enterprise = service.getEnterprise(enterpriseId); Collection<NodeVirtualImage> nvimgs = vdcService.getNodeVirtualImageByEnterprise(enterprise); VirtualMachinesDto vmDto = new VirtualMachinesDto(); for (NodeVirtualImage nvimg : nvimgs) { VirtualAppliance vapp = nvimg.getVirtualAppliance(); VirtualMachine vm = nvimg.getVirtualMachine(); vmDto.add(VirtualMachineResource.createTransferObject(vm, vapp.getVirtualDatacenter(), vapp.getId(), restBuilder, null, null, null)); } return vmDto; } /** * Retrieves the list Of icons urls used in virtual images of an enterprise * * @title Retrive a list of icons of an Enterprise * @param enterpriseId identifier of the enterprise * @param restBuilder {@link IRESTBuilder} object injected by context * @return the list of String * @throws Exception */ @GET @Path(EnterpriseResource.ENTERPRISE_ACTION_GET_ICONS_PATH) public List<String> getIconsByEnterprise( @PathParam(EnterpriseResource.ENTERPRISE) final Integer enterpriseId, @Context final IRESTBuilder restBuilder) throws Exception { // check if the enterprise exists Enterprise enterprise = service.getEnterprise(enterpriseId); return vmtService.findIconsByEnterprise(enterprise.getId()); } /** * Retrieves the list Of Virtual datacenters defined into an enterprise. * * @title Retrieve a list of vitual datacenters by an Enterprise * @param enterpriseId identifier of the enterprise * @param restBuilder {@linnk IRESTBuilder} object injected by context * @return the {@link VirtualDatacentersDto} object. A {@link VirtualDatacenterDto} wrapper. * @throws Exception */ @GET @Path(EnterpriseResource.ENTERPRISE_ACTION_GET_VIRTUALDATACENTERS_PATH) @Produces(VirtualDatacentersDto.MEDIA_TYPE) public VirtualDatacentersDto getVirtualDatacenters( @PathParam(EnterpriseResource.ENTERPRISE) final Integer enterpriseId, @QueryParam(START_WITH) @DefaultValue("0") @Min(0) final Integer startwith, @QueryParam(LIMIT) @DefaultValue(DEFAULT_PAGE_LENGTH_STRING) @Min(1) final Integer limit, @QueryParam(BY) @DefaultValue("name") final String orderBy, @QueryParam(FILTER) @DefaultValue("") final String filter, @QueryParam(ASC) @DefaultValue("true") final Boolean asc, @Context final IRESTBuilder restBuilder) throws Exception { FilterOptions filterOptions = new FilterOptions(startwith, limit, filter, orderBy, asc); Enterprise enterprise = service.getEnterprise(enterpriseId); Collection<VirtualDatacenter> all = vdcService.getVirtualDatacenters(enterprise, null, filterOptions); VirtualDatacentersDto vdcs = new VirtualDatacentersDto(); for (VirtualDatacenter d : all) { vdcs.add(VirtualDatacenterResource.createTransferObject(d, restBuilder)); } if (!all.isEmpty()) { vdcs.setTotalSize(((PagedList< ? >) all).getTotalResults()); vdcs.addLinks(restBuilder.buildPaggingLinks(uriInfo.getAbsolutePath().toString(), (PagedList< ? >) all)); } return vdcs; } /** * Retrieves the list Of Virtual appliances defined into an enterprise. * * @title Retrieve the list of virtual appliances by an Enterprise * @param enterpriseId identifier of the enterprise * @param restBuilder {@linnk IRESTBuilder} object injected by context * @return the {@link VirtualAppliancesDto} object. A {@link VirtualApplianceDto} wrapper. * @throws Exception */ @GET @Produces(VirtualAppliancesDto.MEDIA_TYPE) @Path(EnterpriseResource.ENTERPRISE_ACTION_GET_VIRTUALAPPLIANCES_PATH) public VirtualAppliancesDto getVirtualAppliances( @PathParam(EnterpriseResource.ENTERPRISE) final Integer enterpriseId, @QueryParam(START_WITH) @DefaultValue("0") @Min(0) final Integer startwith, @QueryParam(LIMIT) @DefaultValue(DEFAULT_PAGE_LENGTH_STRING) @Min(1) final Integer limit, @QueryParam(BY) @DefaultValue("name") final String orderBy, @QueryParam(FILTER) @DefaultValue("") final String filter, @QueryParam(ASC) @DefaultValue("true") final Boolean asc, @QueryParam(value = "expand") final String expand, @Context final IRESTBuilder restBuilder) throws Exception { FilterOptions filterOptions = new FilterOptions(startwith, limit, filter, orderBy, asc); List<VirtualAppliance> all = vappService.getVirtualAppliancesByEnterprise(enterpriseId, filterOptions); VirtualAppliancesDto vappsDtos = new VirtualAppliancesDto(); if (all != null && !all.isEmpty()) { for (VirtualAppliance vapp : all) { VirtualApplianceDto dto = VirtualApplianceResource.createTransferObject(vapp, restBuilder); if (!StringUtils.isBlank(expand)) { this.expandNodes(expand, uriInfo, vapp, dto); } vappsDtos.getCollection().add(dto); } } if (all.isEmpty() == false) { vappsDtos.setTotalSize(((PagedList< ? >) all).getTotalResults()); } return vappsDtos; } private void expandNodes(final String expand, final UriInfo uriInfo, final VirtualAppliance app, final VirtualApplianceDto dto) { String[] expands = StringUtils.split(expand, ","); if (expands != null) { for (String e : expands) { if ("last_task".equalsIgnoreCase(e)) { List<Task> lastTasks = vappService.getAllNodesLastTask(app.getVirtualDatacenter().getId(), app.getId()); if (lastTasks != null && !lastTasks.isEmpty()) { TasksDto t = TaskResourceUtils.transform(lastTasks, uriInfo); dto.setLastTasks(t); } } } } } private static EnterpriseDto addLinks(final IRESTBuilder restBuilder, final EnterpriseDto enterprise) { enterprise.setLinks(restBuilder.buildEnterpriseLinks(enterprise)); return enterprise; } public static EnterpriseDto createTransferObject(final Enterprise e, final IRESTBuilder restBuilder) throws Exception { EnterpriseDto dto = new EnterpriseDto(); dto.setId(e.getId()); dto.setName(e.getName()); dto.setCpuCountHardLimit(e.getCpuCountHardLimit().intValue()); dto.setCpuCountSoftLimit(e.getCpuCountSoftLimit().intValue()); dto.setHdHardLimitInMb(e.getHdHardLimitInMb()); dto.setHdSoftLimitInMb(e.getHdSoftLimitInMb()); dto.setPublicIpsHard(e.getPublicIpsHard()); dto.setPublicIpsSoft(e.getPublicIpsSoft()); dto.setVlansHard(e.getVlanHard()); dto.setVlansSoft(e.getVlanSoft()); dto.setRamHardLimitInMb(e.getRamHardLimitInMb().intValue()); dto.setRamSoftLimitInMb(e.getRamSoftLimitInMb().intValue()); dto.setStorageHard(e.getStorageHard()); dto.setStorageSoft(e.getStorageSoft()); dto.setRepositorySoft(e.getRepositorySoft()); dto.setRepositoryHard(e.getRepositoryHard()); dto.setChefURL(e.getChefURL()); dto.setChefClient(e.getChefClient()); dto.setChefValidator(e.getChefValidator()); dto.setChefClientCertificate(e.getChefClientCertificate()); dto.setChefValidatorCertificate(e.getChefValidatorCertificate()); dto.setIsReservationRestricted(e.getIsReservationRestricted()); if (e.getPricingTemplate() != null) { dto.setIdPricingTemplate(e.getPricingTemplate().getId()); } dto = addLinks(restBuilder, dto); return dto; } }