package org.openstack.atlas.api.resources; import org.apache.abdera.model.Feed; import org.openstack.atlas.api.atom.FeedType; import org.openstack.atlas.api.helpers.LoadBalancerProperties; 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.HttpRequestType; import org.openstack.atlas.api.validation.results.ValidatorResult; import org.openstack.atlas.docs.loadbalancers.api.v1.NodeServiceEvents; import org.openstack.atlas.docs.loadbalancers.api.v1.Nodes; import org.openstack.atlas.service.domain.entities.LoadBalancer; import org.openstack.atlas.service.domain.entities.LoadBalancerStatus; import org.openstack.atlas.service.domain.entities.Node; import org.openstack.atlas.service.domain.events.entities.NodeServiceEvent; import org.openstack.atlas.service.domain.exceptions.BadRequestException; import org.openstack.atlas.service.domain.exceptions.ImmutableEntityException; import org.openstack.atlas.service.domain.operations.Operation; import org.openstack.atlas.service.domain.pojos.MessageDataContainer; import javax.ws.rs.*; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import java.util.*; import static javax.ws.rs.core.MediaType.*; public class NodesResource extends CommonDependencyProvider { private NodeResource nodeResource; private Integer accountId; private Integer loadBalancerId; private HttpHeaders requestHeaders; @GET @Produces({APPLICATION_XML, APPLICATION_JSON, APPLICATION_ATOM_XML}) public Response retrieveNodes(@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, FeedType.NODES_FEED); } Set<Node> dnodes; Nodes rnodes = new Nodes(); try { dnodes = nodeService.getNodesByAccountIdLoadBalancerId(getAccountId(), getLoadBalancerId(), offset, limit, marker); dnodes = LoadBalancerProperties.setWeightsforNodes(dnodes); for (org.openstack.atlas.service.domain.entities.Node dnode : dnodes) { rnodes.getNodes().add(dozerMapper.map(dnode, org.openstack.atlas.docs.loadbalancers.api.v1.Node.class, "HIDE_NODE_META")); } return Response.status(200).entity(rnodes).build(); } catch (Exception e) { return ResponseFactory.getErrorResponse(e, null, null); } } @DELETE @Produces({APPLICATION_XML, APPLICATION_JSON, APPLICATION_ATOM_XML}) public Response deleteNodes(@QueryParam("id") List<Integer> nodeIds) { MessageDataContainer msg = new MessageDataContainer(); boolean isLbEditable; LoadBalancer dlb = new LoadBalancer(); List<String> validationErrors; dlb.setId(loadBalancerId); Collections.sort(nodeIds); try { if (nodeIds.isEmpty()) { BadRequestException badRequestException = new BadRequestException("Must supply one or more id's to process this request."); return ResponseFactory.getErrorResponse(badRequestException, null, null); } isLbEditable = loadBalancerService.testAndSetStatusPending(accountId, loadBalancerId); if (!isLbEditable) { throw new ImmutableEntityException("LoadBalancer is not ACTIVE"); } validationErrors = nodeService.prepareForNodesDeletion(accountId, loadBalancerId, nodeIds); if (validationErrors.size() > 0) { loadBalancerService.setStatus(dlb, LoadBalancerStatus.ACTIVE); return getValidationFaultResponse(validationErrors); } msg.setIds(nodeIds); msg.setAccountId(accountId); msg.setLoadBalancerId(loadBalancerId); msg.setUserName(getUserName(requestHeaders)); asyncService.callAsyncLoadBalancingOperation(Operation.DELETE_NODES, msg); } catch (Exception ex) { return ResponseFactory.getErrorResponse(ex, null, null); } return Response.status(202).build(); } @POST @Consumes({APPLICATION_XML, APPLICATION_JSON}) public Response createNodes(Nodes nodes) { ValidatorResult result = ValidatorRepository.getValidatorFor(Nodes.class).validate(nodes, HttpRequestType.POST); if (!result.passedValidation()) { return getValidationFaultResponse(result); } try { List<String> errors; List<org.openstack.atlas.docs.loadbalancers.api.v1.Node> nodesList = nodes.getNodes(); errors = verifyNodeDomains(nodesList); if (errors.size() > 0) { return getValidationFaultResponse(errors); } loadBalancerService.get(loadBalancerId, accountId); org.openstack.atlas.docs.loadbalancers.api.v1.LoadBalancer apiLb = new org.openstack.atlas.docs.loadbalancers.api.v1.LoadBalancer(); apiLb.getNodes().addAll(nodesList); LoadBalancer newNodesLb = dozerMapper.map(apiLb, LoadBalancer.class); newNodesLb.setId(loadBalancerId); newNodesLb.setAccountId(accountId); newNodesLb.setUserName(getUserName(requestHeaders)); Nodes returnNodes = new Nodes(); Set<Node> dbnodes = nodeService.createNodes(newNodesLb); for (Node node : dbnodes) { returnNodes.getNodes().add(dozerMapper.map(node, org.openstack.atlas.docs.loadbalancers.api.v1.Node.class)); } asyncService.callAsyncLoadBalancingOperation(Operation.CREATE_NODES, newNodesLb); return Response.status(Response.Status.ACCEPTED).entity(returnNodes).build(); } catch (Exception e) { return ResponseFactory.getErrorResponse(e, null, null); } } @GET @Path("events") @Produces({APPLICATION_XML, APPLICATION_JSON, APPLICATION_ATOM_XML}) public Response retrieveNodeEvents(@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, FeedType.NODE_SERVICE_FEED); } List<NodeServiceEvent> dEvents; NodeServiceEvents rEvents = new NodeServiceEvents(); try { dEvents = loadBalancerEventRepository.getNodeServiceEvents(accountId, loadBalancerId, page, offset, limit, marker); for (NodeServiceEvent event : dEvents) { rEvents.getNodeServiceEvents().add(dozerMapper.map(event, org.openstack.atlas.docs.loadbalancers.api.v1.NodeServiceEvent.class)); } return Response.status(200).entity(rEvents).build(); } catch (Exception e) { return ResponseFactory.getErrorResponse(e, null, null); } } @Path("{id: [-+]?[1-9][0-9]*}") public NodeResource retrieveNodeResource(@PathParam("id") int id) { nodeResource.setRequestHeaders(requestHeaders); nodeResource.setId(id); nodeResource.setAccountId(accountId); nodeResource.setLoadBalancerId(loadBalancerId); return nodeResource; } private Response getFeedResponse(Integer page, FeedType feedType) { Map<String, Object> feedAttributes = new HashMap<String, Object>(); feedAttributes.put("feedType", feedType); feedAttributes.put("accountId", accountId); feedAttributes.put("loadBalancerId", loadBalancerId); feedAttributes.put("page", page); Feed feed = atomFeedAdapter.getFeed(feedAttributes); if (feed.getEntries().isEmpty()) { try { nodeService.getNodesByAccountIdLoadBalancerId(getAccountId(), getLoadBalancerId()); } catch (Exception e) { return ResponseFactory.getErrorResponse(e, null, null); } } return Response.status(200).entity(feed).build(); } public void setNodeResource(NodeResource nodeResource) { this.nodeResource = nodeResource; } public void setAccountId(Integer accountId) { this.accountId = accountId; } public Integer getAccountId() { return accountId; } public int getLoadBalancerId() { return loadBalancerId; } public void setLoadBalancerId(Integer loadBalancerId) { this.loadBalancerId = loadBalancerId; } public void setRequestHeaders(HttpHeaders requestHeaders) { this.requestHeaders = requestHeaders; } }