org.apache.usergrid.chop.webapp.coordinator.rest.UploadResource.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.usergrid.chop.webapp.coordinator.rest.UploadResource.java

Source

/*
 *  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 org.apache.usergrid.chop.webapp.coordinator.rest;

import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Nullable;
import javax.mail.internet.MimeMultipart;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.usergrid.chop.webapp.ChopUiFig;
import org.apache.usergrid.chop.webapp.coordinator.CoordinatorUtils;
import org.apache.usergrid.chop.webapp.dao.model.BasicCommit;
import org.apache.usergrid.chop.webapp.dao.model.BasicRun;
import org.apache.usergrid.chop.webapp.dao.model.BasicRunResult;
import org.apache.usergrid.chop.webapp.elasticsearch.Util;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import org.apache.usergrid.chop.api.Commit;
import org.apache.usergrid.chop.api.Module;
import org.apache.usergrid.chop.api.RestParams;
import org.apache.usergrid.chop.webapp.dao.CommitDao;
import org.apache.usergrid.chop.webapp.dao.ModuleDao;
import org.apache.usergrid.chop.webapp.dao.RunDao;
import org.apache.usergrid.chop.webapp.dao.RunResultDao;
import org.apache.usergrid.chop.webapp.dao.model.BasicModule;
import org.safehaus.jettyjam.utils.TestMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.sun.jersey.multipart.FormDataParam;

/**
 * REST operation to upload (a.k.a. deploy) a project war file.
 */
@Singleton
@Produces(MediaType.TEXT_PLAIN)
@Path(UploadResource.ENDPOINT)
public class UploadResource extends TestableResource implements RestParams {
    public final static String ENDPOINT = "/upload";
    public final static String SUCCESSFUL_TEST_MESSAGE = "Test parameters are OK";
    private final static Logger LOG = LoggerFactory.getLogger(UploadResource.class);

    @Inject
    private ChopUiFig chopUiFig;

    @Inject
    private ModuleDao moduleDao;

    @Inject
    private RunDao runDao;

    @Inject
    private RunResultDao runResultDao;

    @Inject
    private CommitDao commitDao;

    public UploadResource() {
        super(ENDPOINT);
    }

    /**
     * Uploads a file to the servlet context temp directory. More for testing proper uploads.
     */
    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.APPLICATION_JSON)
    public Response upload(MimeMultipart multipart) {
        try {
            String filename = multipart.getBodyPart(0).getContent().toString();
            LOG.warn("FILENAME: " + filename);
            InputStream in = multipart.getBodyPart(1).getInputStream();
            File tempDir = new File(chopUiFig.getContextTempDir());
            String fileLocation = new File(tempDir, filename).getAbsolutePath();
            CoordinatorUtils.writeToFile(in, fileLocation);
        } catch (Exception ex) {
            LOG.error("upload", ex);
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ex.getMessage()).build();
        }

        return Response.status(Response.Status.CREATED).entity("ok").build();
    }

    /**
     * Uploads an executable runner jar into a special path in the temp directory for the application.
     */
    @POST
    @Path("/runner")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public Response uploadRunner(

            @FormDataParam(COMMIT_ID) String commitId, @FormDataParam(MODULE_GROUPID) String groupId,
            @FormDataParam(MODULE_ARTIFACTID) String artifactId, @FormDataParam(MODULE_VERSION) String version,
            @FormDataParam(USERNAME) String username, @FormDataParam(VCS_REPO_URL) String vcsRepoUrl,
            @FormDataParam(TEST_PACKAGE) String testPackage, @FormDataParam(MD5) String md5,
            @FormDataParam(CONTENT) InputStream runnerJarStream,
            @Nullable @QueryParam(TestMode.TEST_MODE_PROPERTY) String testMode

    ) throws Exception {

        if (inTestMode(testMode)) {
            LOG.info("Calling /upload/runner in test mode ...");
        } else {
            LOG.info("/upload/runner called ...");
        }

        LOG.debug("extracted {} = {}", RestParams.COMMIT_ID, commitId);
        LOG.debug("extracted {} = {}", RestParams.MODULE_GROUPID, groupId);
        LOG.debug("extracted {} = {}", RestParams.MODULE_ARTIFACTID, artifactId);
        LOG.debug("extracted {} = {}", RestParams.MODULE_VERSION, version);
        LOG.debug("extracted {} = {}", RestParams.USERNAME, username);
        LOG.debug("extracted {} = {}", RestParams.VCS_REPO_URL, vcsRepoUrl);
        LOG.debug("extracted {} = {}", RestParams.TEST_PACKAGE, testPackage);
        LOG.debug("extracted {} = {}", RestParams.MD5, md5);

        if (inTestMode(testMode)) {
            return Response.status(Response.Status.CREATED).entity(SUCCESSFUL_TEST_MESSAGE)
                    .type(MediaType.TEXT_PLAIN).build();
        }

        File runnerJar = CoordinatorUtils.getRunnerJar(chopUiFig.getContextPath(), username, groupId, artifactId,
                version, commitId);

        if (!runnerJar.getParentFile().exists()) {
            if (runnerJar.getParentFile().mkdirs()) {
                LOG.info("Created parent directory {} for uploaded runner file", runnerJar.getAbsolutePath());
            } else {
                String errorMessage = "Failed to create parent directory " + runnerJar.getAbsolutePath()
                        + " for uploaded runner file.";
                LOG.error(errorMessage);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build();
            }
        }

        // Download and write the file to the proper position on disk & reference
        CoordinatorUtils.writeToFile(runnerJarStream, runnerJar.getAbsolutePath());

        // - this is bad news because we will get commits of other users :(
        // - we also need to qualify the commit with username, groupId,
        //   and the version of module as well

        Commit commit = null;
        Module module = null;

        List<Commit> commits = commitDao.getByModule(artifactId);
        for (Commit returnedCommit : commits) {
            Module commitModule = moduleDao.get(returnedCommit.getModuleId());
            if (commitModule.getArtifactId().equals(artifactId) && commitModule.getGroupId().equals(groupId)
                    && commitModule.getVersion().equals(version)) {
                commit = returnedCommit;
                module = commitModule;
            }
        }

        if (module == null) {
            module = new BasicModule(groupId, artifactId, version, vcsRepoUrl, testPackage);
            moduleDao.save(module);
        }

        if (commit == null) {
            commit = new BasicCommit(commitId, module.getId(), md5, new Date(), runnerJar.getAbsolutePath());
            commitDao.save(commit);
        }

        return Response.status(Response.Status.CREATED).entity(runnerJar.getAbsolutePath()).build();
    }

    @SuppressWarnings("unchecked")
    @POST
    @Path("/results")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public Response uploadResults(MimeMultipart multipart) throws Exception {
        String runId = multipart.getBodyPart(RestParams.RUN_ID).getContent().toString();
        LOG.debug("extracted {} = {}", RestParams.RUN_ID, runId);

        InputStream in = multipart.getBodyPart(RestParams.CONTENT).getInputStream();

        JSONObject object = (JSONObject) new JSONParser().parse(new InputStreamReader(in));
        JSONArray runResults = (JSONArray) object.get("runResults");
        Iterator<JSONObject> iterator = runResults.iterator();

        //noinspection WhileLoopReplaceableByForEach
        while (iterator.hasNext()) {
            JSONObject jsonResult = iterator.next();

            BasicRunResult runResult = new BasicRunResult(runId, Util.getInt(jsonResult, "runCount"),
                    Util.getInt(jsonResult, "runTime"), Util.getInt(jsonResult, "ignoreCount"),
                    Util.getInt(jsonResult, "failureCount"));

            if (runResultDao.save(runResult)) {
                LOG.info("Saved run result: {}", runResult);
            }
        }

        return Response.status(Response.Status.CREATED).entity("TRUE").build();
    }

    @POST
    @Path("/summary")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public Response uploadSummary(MimeMultipart multipart) throws Exception {
        String runnerHostname = multipart.getBodyPart(RestParams.RUNNER_HOSTNAME).getContent().toString();
        LOG.debug("extracted {} = {}", RestParams.RUNNER_HOSTNAME, runnerHostname);

        InputStream in = multipart.getBodyPart(RestParams.CONTENT).getInputStream();

        JSONObject json = (JSONObject) new JSONParser().parse(new InputStreamReader(in));
        BasicRun run = new BasicRun(COMMIT_ID, runnerHostname, Util.getInt(json, "runNumber"),
                Util.getString(json, "testName"));
        run.copyJson(json);

        if (runDao.save(run)) {
            LOG.info("Created new Run {} ", run);
        } else {
            LOG.warn("Failed to create new Run");
        }

        return Response.status(Response.Status.CREATED).entity(run.getId()).build();
    }
}