package org.openstack.atlas.api.resources; import org.openstack.atlas.docs.loadbalancers.api.v1.IpVersion; import org.openstack.atlas.docs.loadbalancers.api.v1.VipType; import org.openstack.atlas.service.domain.entities.AccountLimitType; import org.openstack.atlas.service.domain.entities.LoadBalancer; import org.openstack.atlas.service.domain.entities.VirtualIp; import org.openstack.atlas.service.domain.entities.VirtualIpv6; import org.openstack.atlas.service.domain.exceptions.BadRequestException; import org.openstack.atlas.service.domain.exceptions.EntityNotFoundException; import org.openstack.atlas.service.domain.operations.Operation; import org.openstack.atlas.service.domain.pojos.MessageDataContainer; import org.openstack.atlas.api.atom.FeedType; import org.openstack.atlas.api.faults.HttpResponseBuilder; import org.openstack.atlas.api.helpers.ResponseFactory; import org.openstack.atlas.api.repository.ValidatorRepository; import org.openstack.atlas.api.resources.providers.CommonDependencyProvider; import org.openstack.atlas.api.validation.context.VirtualIpContext; import org.openstack.atlas.api.validation.results.ValidatorResult; import org.apache.abdera.model.Feed; import javax.ws.rs.*; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.*; import static org.openstack.atlas.api.filters.helpers.StringUtilities.getExtendedStackTrace; import static javax.ws.rs.core.MediaType.*; public class VirtualIpsResource extends CommonDependencyProvider { private VirtualIpResource virtualIpResource; private Integer accountId; private Integer loadBalancerId; private HttpHeaders requestHeaders; @GET @Produces({APPLICATION_XML, APPLICATION_JSON, APPLICATION_ATOM_XML}) public Response retrieveAllVirtualIps(@QueryParam("offset") Integer offset, @QueryParam("limit") Integer limit, @QueryParam("marker") Integer marker, @QueryParam("page") Integer page) { if (requestHeaders.getRequestHeader("Accept").get(0).equals(APPLICATION_ATOM_XML)) { return getFeedResponse(page); } org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIps rvips = new org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIps(); try { loadBalancerService.get(loadBalancerId, accountId); try { Set<VirtualIp> ipv4Vips = virtualIpService.get(accountId, loadBalancerId, offset, limit, marker); for (org.openstack.atlas.service.domain.entities.VirtualIp ipv4Vip : ipv4Vips) { org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp apiIpv4Vip = dozerMapper.map(ipv4Vip, org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp.class); apiIpv4Vip.setIpVersion(IpVersion.IPV4); rvips.getVirtualIps().add(apiIpv4Vip); } } catch (EntityNotFoundException enfe) { // Ignore since we still need to check for IPv6 vips. } Set<VirtualIpv6> ipv6Vips = virtualIpService.getVirtualIpv6ByLoadBalancerId(loadBalancerId); for (org.openstack.atlas.service.domain.entities.VirtualIpv6 ipv6Vip : ipv6Vips) { org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp apiIpv6Vip; apiIpv6Vip = new org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp(); apiIpv6Vip.setId(ipv6Vip.getId()); apiIpv6Vip.setType(VipType.PUBLIC); apiIpv6Vip.setIpVersion(IpVersion.IPV6); apiIpv6Vip.setAddress(virtualIpService.getVirtualIpv6String(ipv6Vip)); rvips.getVirtualIps().add(apiIpv6Vip); } return Response.status(200).entity(rvips).build(); } catch (Exception e) { return ResponseFactory.getErrorResponse(e, null, null); } } @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response addIpv6VirtualIpToLoadBalancer(org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp vip) { ValidatorResult result = ValidatorRepository.getValidatorFor(org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp.class).validate(vip, VirtualIpContext.POST_IPV6); if (!result.passedValidation()) { return Response.status(400).entity(HttpResponseBuilder.buildBadRequestResponse("Validation fault", result.getValidationErrorMessages())).build(); } try { VirtualIpv6 domainVirtualIpv6 = new VirtualIpv6(); domainVirtualIpv6.setId(vip.getId()); domainVirtualIpv6.setAccountId(accountId); LoadBalancer domainLb = new LoadBalancer(); domainLb.setId(loadBalancerId); domainLb.setAccountId(accountId); VirtualIpv6 newlyAddedIpv6Vip = virtualIpService.addIpv6VirtualIpToLoadBalancer(domainVirtualIpv6, domainLb); MessageDataContainer dataContainer = new MessageDataContainer(); dataContainer.setAccountId(accountId); dataContainer.setLoadBalancerId(loadBalancerId); dataContainer.getNewVipIds().add(newlyAddedIpv6Vip.getId()); if (requestHeaders != null) dataContainer.setUserName(requestHeaders.getRequestHeader("X-PP-User").get(0)); asyncService.callAsyncLoadBalancingOperation(Operation.ADD_VIRTUAL_IP, dataContainer); org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp returnVip = new org.openstack.atlas.docs.loadbalancers.api.v1.VirtualIp(); returnVip.setId(newlyAddedIpv6Vip.getId()); returnVip.setType(VipType.PUBLIC); returnVip.setIpVersion(IpVersion.IPV6); returnVip.setAddress(newlyAddedIpv6Vip.getDerivedIpString()); return Response.status(Response.Status.ACCEPTED).entity(returnVip).build(); } catch (Exception e) { String msg = getExtendedStackTrace(e); return ResponseFactory.getErrorResponse(e, null, null); } } @DELETE @Produces({APPLICATION_XML, APPLICATION_JSON, APPLICATION_ATOM_XML}) public Response deleteVirtualIps(@QueryParam("id") Set<Integer> virtualIpIds) { try { if (virtualIpIds.isEmpty()) { BadRequestException badRequestException = new BadRequestException("Must supply one or more id's to process this request."); return ResponseFactory.getErrorResponse(badRequestException, null, null); } Integer limit = accountLimitService.getLimit(accountId, AccountLimitType.BATCH_DELETE_LIMIT); if (virtualIpIds.size() > limit) { BadRequestException badRequestException = new BadRequestException(String.format("Currently, the limit of accepted parameters is: %s : please supply a valid parameter list.", limit)); return ResponseFactory.getErrorResponse(badRequestException, null, null); } List<Integer> vipIds = new ArrayList<Integer>(virtualIpIds); virtualIpService.prepareForVirtualIpsDeletion(accountId, loadBalancerId, vipIds); MessageDataContainer messageDataContainer = new MessageDataContainer(); messageDataContainer.setIds(vipIds); messageDataContainer.setAccountId(accountId); messageDataContainer.setLoadBalancerId(loadBalancerId); asyncService.callAsyncLoadBalancingOperation(Operation.DELETE_VIRTUAL_IPS, messageDataContainer); return Response.status(202).build(); } catch (Exception e) { return ResponseFactory.getErrorResponse(e, null, null); } } @Path("{id: [-+]?[0-9][0-9]*}") public VirtualIpResource retrieveVirtualIpResource(@PathParam("id") int virtualIpId) { virtualIpResource.setRequestHeaders(requestHeaders); virtualIpResource.setLoadBalancerId(loadBalancerId); virtualIpResource.setId(virtualIpId); virtualIpResource.setAccountId(accountId); return virtualIpResource; } private Response getFeedResponse(Integer page) { Map<String, Object> feedAttributes = new HashMap<String, Object>(); feedAttributes.put("feedType", FeedType.VIRTUAL_IPS_FEED); feedAttributes.put("accountId", accountId); feedAttributes.put("loadBalancerId", loadBalancerId); feedAttributes.put("page", page); Feed feed = atomFeedAdapter.getFeed(feedAttributes); if (feed.getEntries().isEmpty()) { try { lbRepository.getVipsByLoadBalancerId(loadBalancerId); } catch (Exception e) { return ResponseFactory.getErrorResponse(e, null, null); } } return Response.status(200).entity(feed).build(); } public void setVirtualIpResource(VirtualIpResource virtualIpResource) { this.virtualIpResource = virtualIpResource; } public void setAccountId(Integer accountId) { this.accountId = accountId; } public void setLoadBalancerId(Integer loadBalancerId) { this.loadBalancerId = loadBalancerId; } public void setRequestHeaders(HttpHeaders requestHeaders) { this.requestHeaders = requestHeaders; } }