001package org.maxur.perfmodel.backend.rest.resources;
002
003import com.fasterxml.jackson.core.JsonFactory;
004import com.fasterxml.jackson.core.type.TypeReference;
005import com.fasterxml.jackson.databind.ObjectMapper;
006import com.google.common.base.Charsets;
007import com.google.common.io.Resources;
008import org.jsondoc.core.annotation.*;
009import org.jsondoc.core.pojo.ApiVerb;
010import org.maxur.perfmodel.backend.service.Application;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014import javax.inject.Inject;
015import javax.inject.Named;
016import javax.ws.rs.*;
017import javax.ws.rs.core.MediaType;
018import javax.ws.rs.core.Response;
019import java.io.IOException;
020import java.net.URL;
021import java.util.HashMap;
022import java.util.Map;
023
024import static org.maxur.perfmodel.backend.rest.WebException.badRequestException;
025import static org.maxur.perfmodel.backend.utils.DateTimeUtils.schedule;
026
027/**
028 * @author Maxim Yunusov
029 * @version 1.0
030 * @since <pre>11/29/13</pre>
031 */
032@Path("/{a:application}")
033@Api(name = "Application Resource", description = "Methods for managing PMC Application")
034@ApiVersion(since = "1.0")
035public class ApplicationResource {
036
037    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationResource.class);
038
039    @Inject
040    private Application application;
041
042    @SuppressWarnings("unused")
043    @Named("api.url")
044    private String apiUrl;
045
046    @SuppressWarnings("unused")
047    @Named("delay.before.stop")
048    private Integer delayBeforeStop;
049
050
051    @GET
052    @Path("/jsondoc")
053    @Produces(MediaType.APPLICATION_JSON)
054    @ApiMethod(
055            path = "/application/jsondoc",
056            verb = ApiVerb.GET,
057            description = "Gets a application documentation",
058            produces = { MediaType.APPLICATION_JSON },
059            responsestatuscode = "200 - OK"
060    )
061    @ApiErrors(apierrors={
062            @ApiError(code="500", description="Application critical error")
063    })
064    @ApiResponseObject
065    public String getJsonDoc() {
066        URL url = Resources.getResource("jsondoc.json");
067        try {
068            final String jsonDoc = Resources.toString(url, Charsets.UTF_8);
069            return jsonDoc.replaceAll("http://127.0.0.1:8080/api", apiUrl);
070        } catch (IOException e) {
071            throw new IllegalStateException(e);
072        }
073    }
074
075    @GET
076    @Path("/version")
077    @Produces(MediaType.APPLICATION_JSON)
078    @ApiMethod(
079        path = "/application/version",
080        verb = ApiVerb.GET,
081        description = "Gets a application version",
082        produces = { MediaType.APPLICATION_JSON },
083        responsestatuscode = "200 - OK"
084    )
085    @ApiErrors(apierrors={
086            @ApiError(code="500", description="Application critical error")
087    })
088    @ApiResponseObject
089    public String getVersion() {
090        return application.version();
091    }
092
093    @PUT
094    @Path("/status")
095    @Consumes(MediaType.APPLICATION_JSON)
096    @Produces(MediaType.APPLICATION_JSON)
097    @ApiMethod(
098            path = "/application/status",
099            verb = ApiVerb.PUT,
100            description = "Sets a application status to stopped",
101            produces = { MediaType.APPLICATION_JSON },
102            consumes = { MediaType.APPLICATION_JSON },
103            responsestatuscode = "200 - OK"
104    )
105    @ApiErrors(apierrors={
106            @ApiError(code="500", description="Application critical error")
107    })
108    public Response action(@ApiBodyObject final String object) {
109        try {
110            final ObjectMapper mapper = new ObjectMapper(new JsonFactory());
111            final Map<String, Object> map = mapper.readValue(object, new TypeReference<HashMap<String, Object>>() {
112            });
113            final String status = (String) map.get("status");
114            switch (status) {
115                case "stopped":
116                    schedule(application::stop, delayBeforeStop);
117                    break;
118                default:
119                    throw badRequestException("Status '%s' is not valid", status);
120            }
121            return Response.status(Response.Status.ACCEPTED).build();
122        } catch (IOException e) {
123            LOGGER.error("Operation is not valid", e);
124            throw badRequestException("Operation is not valid", e.getMessage());
125        }
126    }
127}