com.redhat.rhn.frontend.xmlrpc.system.crash.CrashHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.redhat.rhn.frontend.xmlrpc.system.crash.CrashHandler.java

Source

/**
 * Copyright (c) 2013--2014 Red Hat, Inc.
 *
 * This software is licensed to you under the GNU General Public License,
 * version 2 (GPLv2). There is NO WARRANTY for this software, express or
 * implied, including the implied warranties of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
 * along with this software; if not, see
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * Red Hat trademarks are not licensed under GPLv2. No permission is
 * granted to use or replicate Red Hat trademarks that are incorporated
 * in this software or its documentation.
 */

package com.redhat.rhn.frontend.xmlrpc.system.crash;

import com.redhat.rhn.common.conf.Config;
import com.redhat.rhn.common.conf.ConfigDefaults;
import com.redhat.rhn.domain.rhnpackage.PackageArch;
import com.redhat.rhn.domain.rhnpackage.PackageEvr;
import com.redhat.rhn.domain.rhnpackage.PackageEvrFactory;
import com.redhat.rhn.domain.rhnpackage.PackageFactory;
import com.redhat.rhn.domain.rhnpackage.PackageName;
import com.redhat.rhn.domain.server.Crash;
import com.redhat.rhn.domain.server.CrashCount;
import com.redhat.rhn.domain.server.CrashFactory;
import com.redhat.rhn.domain.server.CrashFile;
import com.redhat.rhn.domain.server.CrashNote;
import com.redhat.rhn.domain.server.Server;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.xmlrpc.BaseHandler;
import com.redhat.rhn.frontend.xmlrpc.NoCrashesFoundException;
import com.redhat.rhn.frontend.xmlrpc.CrashFileDownloadException;
import com.redhat.rhn.frontend.xmlrpc.RhnXmlRpcServer;
import com.redhat.rhn.frontend.dto.CrashSystemsDto;
import com.redhat.rhn.frontend.dto.IdenticalCrashesDto;
import com.redhat.rhn.frontend.xmlrpc.system.XmlRpcSystemHelper;
import com.redhat.rhn.manager.download.DownloadManager;
import com.redhat.rhn.manager.system.CrashManager;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * CrashHandler
 * @version $Rev$
 * @xmlrpc.namespace system.crash
 * @xmlrpc.doc Provides methods to access and modify software crash information.
 */
public class CrashHandler extends BaseHandler {

    private static float freeMemCoeff = 0.9f;

    private CrashCount getCrashCount(Server serverIn) {
        CrashCount crashCount = serverIn.getCrashCount();
        if (crashCount == null) {
            throw new NoCrashesFoundException();
        }
        return crashCount;
    }

    /**
     * Return crash count information
     * @param loggedInUser The current user
     * @param serverId Server ID
     * @return Return crash count information
     *
     * @xmlrpc.doc Return date of last software crashes report for given system
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "serverId")
     * @xmlrpc.returntype
     *     #struct("Crash Count Information")
     *         #prop_desc("int", "total_count",
     *                    "Total number of software crashes for a system")
     *         #prop_desc("int", "unique_count",
     *                    "Number of unique software crashes for a system")
     *         #prop_desc("dateTime.iso8601", "last_report",
     *                    "Date of the last software crash report")
     *     #struct_end()
     */
    public Map getCrashCountInfo(User loggedInUser, Integer serverId) {
        XmlRpcSystemHelper sysHelper = XmlRpcSystemHelper.getInstance();
        Server server = sysHelper.lookupServer(loggedInUser, serverId);

        Map returnMap = new HashMap();
        CrashCount crashCount = null;

        try {
            crashCount = getCrashCount(server);
        } catch (NoCrashesFoundException e) {
            returnMap.put("total_count", 0);
            returnMap.put("unique_count", 0);
            return returnMap;
        }

        returnMap.put("total_count", crashCount.getTotalCrashCount());
        returnMap.put("unique_count", crashCount.getUniqueCrashCount());
        returnMap.put("last_report", crashCount.getLastReport());

        return returnMap;
    }

    /**
     * Returns list of software crashes for a system.
     * @param loggedInUser The current user
     * @param serverId Server ID
     * @return Returns list of software crashes for given system id.
     *
     * @xmlrpc.doc Return list of software crashes for a system.
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "serverId")
     * @xmlrpc.returntype
     *     #array()
     *         #struct("crash")
     *             #prop("int", "id")
     *             #prop("string", "crash")
     *             #prop("string", "path")
     *             #prop("int", "count")
     *             #prop("string", "uuid")
     *             #prop("string", "analyzer")
     *             #prop("string", "architecture")
     *             #prop("string", "cmdline")
     *             #prop("string", "component")
     *             #prop("string", "executable")
     *             #prop("string", "kernel")
     *             #prop("string", "reason")
     *             #prop("string", "username")
     *             #prop("date", "created")
     *             #prop("date", "modified")
     *         #struct_end()
     *     #array_end()
     */
    public List listSystemCrashes(User loggedInUser, Integer serverId) {
        XmlRpcSystemHelper sysHelper = XmlRpcSystemHelper.getInstance();
        Server server = sysHelper.lookupServer(loggedInUser, serverId);

        List returnList = new ArrayList();

        for (Crash crash : server.getCrashes()) {
            Map crashMap = new HashMap();
            crashMap.put("id", crash.getId());
            crashMap.put("crash", crash.getCrash());
            crashMap.put("path", crash.getPath());
            crashMap.put("count", crash.getCount());
            crashMap.put("uuid", StringUtils.defaultString(crash.getUuid()));
            crashMap.put("analyzer", StringUtils.defaultString(crash.getAnalyzer()));
            crashMap.put("architecture", StringUtils.defaultString(crash.getArchitecture()));
            crashMap.put("cmdline", StringUtils.defaultString(crash.getCmdline()));
            crashMap.put("component", StringUtils.defaultString(crash.getComponent()));
            crashMap.put("executable", StringUtils.defaultString(crash.getExecutable()));
            crashMap.put("kernel", StringUtils.defaultString(crash.getKernel()));
            crashMap.put("reason", StringUtils.defaultString(crash.getReason()));
            crashMap.put("username", StringUtils.defaultString(crash.getUsername()));
            crashMap.put("created", crash.getCreated());
            crashMap.put("modified", crash.getModified());

            if (crash.getPackageNameId() != null) {
                PackageName pname = PackageFactory.lookupPackageName(crash.getPackageNameId());
                crashMap.put("package_name", pname.getName());
            }

            if (crash.getPackageEvrId() != null) {
                PackageEvr pevr = PackageEvrFactory.lookupPackageEvrById(crash.getPackageEvrId());
                crashMap.put("package_epoch", pevr.getEpoch());
                crashMap.put("package_version", pevr.getVersion());
                crashMap.put("package_release", pevr.getRelease());
            }

            if (crash.getPackageArchId() != null) {
                PackageArch parch = PackageFactory.lookupPackageArchById(crash.getPackageArchId());
                crashMap.put("package_arch", parch.getLabel());
            }

            returnList.add(crashMap);
        }

        return returnList;
    }

    /**
     * Returns list of crash files for a given crash id.
     * @param loggedInUser The current user
     * @param crashId Crash ID
     * @return Returns list of crash files.
     *
     * @xmlrpc.doc Return list of crash files for given crash id.
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "crashId")
     * @xmlrpc.returntype
     *     #array()
     *         #struct("crashFile")
     *             #prop("int", "id")
     *             #prop("string", "filename")
     *             #prop("string", "path")
     *             #prop("int", "filesize")
     *             #prop("boolean", "is_uploaded")
     *             #prop("date", "created")
     *             #prop("date", "modified")
     *         #struct_end()
     *     #array_end()
     */
    public List listSystemCrashFiles(User loggedInUser, Integer crashId) {
        Crash crash = CrashManager.lookupCrashByUserAndId(loggedInUser, new Long(crashId.longValue()));

        List returnList = new ArrayList();

        for (CrashFile crashFile : crash.getCrashFiles()) {
            Map crashMap = new HashMap();
            crashMap.put("id", crashFile.getId());
            crashMap.put("filename", crashFile.getFilename());
            crashMap.put("path", crashFile.getPath());
            crashMap.put("filesize", crashFile.getFilesize());
            crashMap.put("is_uploaded", crashFile.getIsUploaded());
            crashMap.put("created", crashFile.getCreated());
            crashMap.put("modified", crashFile.getModified());
            returnList.add(crashMap);
        }

        return returnList;
    }

    /**
     * Delete a crash with given crash id.
     * @param loggedInUser The current user
     * @param crashId Crash ID
     * @return 1 In case of success, exception otherwise.
     *
     * @xmlrpc.doc Delete a crash with given crash id.
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "crashId")
     * @xmlrpc.returntype #return_int_success()
     */
    public Integer deleteCrash(User loggedInUser, Integer crashId) {
        CrashManager.deleteCrash(loggedInUser, new Long(crashId.longValue()));
        return 1;
    }

    /**
     * Get a crash file download url
     * @param loggedInUser The current user
     * @param crashFileId Crash File ID
     * @return Return a download url string.
     *
     * @xmlrpc.doc Get a crash file download url.
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "crashFileId")
     * @xmlrpc.returntype string - The crash file download url
     */
    public String getCrashFileUrl(User loggedInUser, Integer crashFileId) {
        CrashFile crashFile = CrashManager.lookupCrashFileByUserAndId(loggedInUser,
                new Long(crashFileId.longValue()));

        return RhnXmlRpcServer.getProtocol() + "://" + RhnXmlRpcServer.getServerName()
                + DownloadManager.getCrashFileDownloadPath(crashFile, loggedInUser);
    }

    /**
     * Download a base64 encoded crash file.
     * @param loggedInUser The current user
     * @param crashFileId Crash File ID
     * @return Return a byte array of the crash file.
     * @throws IOException if there is an exception
     *
     * @xmlrpc.doc Download a crash file.
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "crashFileId")
     * @xmlrpc.returntype base64 - base64 encoded crash file.
     */
    public byte[] getCrashFile(User loggedInUser, Integer crashFileId) throws IOException {
        CrashFile crashFile = CrashManager.lookupCrashFileByUserAndId(loggedInUser,
                new Long(crashFileId.longValue()));
        String path = Config.get().getString(ConfigDefaults.MOUNT_POINT) + "/"
                + crashFile.getCrash().getStoragePath() + "/" + crashFile.getFilename();
        File file = new File(path);

        if (file.length() > freeMemCoeff * Runtime.getRuntime().freeMemory()) {
            throw new CrashFileDownloadException("api.crashfile.download.toolarge");
        }

        byte[] plainFile = new byte[(int) file.length()];
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream br = new BufferedInputStream(fis);
        if (br.read(plainFile) != file.length()) {
            throw new CrashFileDownloadException("api.package.download.ioerror");
        }

        fis.close();
        br.close();

        return Base64.encodeBase64(plainFile);
    }

    /**
     * @param loggedInUser The current user
     * @param crashId Crash ID
     * @param subject Crash note subject
     * @param details Crash note details
     * @return 1 on success
     *
     * @xmlrpc.doc Create a crash note
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "crashId")
     * @xmlrpc.param #param("string", "subject")
     * @xmlrpc.param #param("string", "details")
     * @xmlrpc.returntype #return_int_success()
     */
    public int createCrashNote(User loggedInUser, Integer crashId, String subject, String details) {
        if (StringUtils.isBlank(subject)) {
            throw new IllegalArgumentException("Crash note subject is required");
        }
        CrashNote cn = new CrashNote();
        cn.setSubject(subject);
        cn.setNote(details);
        cn.setCreator(loggedInUser);
        cn.setCrash(CrashManager.lookupCrashByUserAndId(loggedInUser, crashId.longValue()));
        CrashFactory.save(cn);
        return 1;
    }

    /**
     * @param loggedInUser The current user
     * @param crashNoteId Crash note ID
     * @return 1 on success
     *
     * @xmlrpc.doc Delete a crash note
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "crashNoteId")
     * @xmlrpc.returntype #return_int_success()
     */
    public int deleteCrashNote(User loggedInUser, Integer crashNoteId) {
        CrashNote cn = CrashManager.lookupCrashNoteByUserAndId(loggedInUser, crashNoteId.longValue());
        CrashFactory.delete(cn);
        return 1;
    }

    /**
     * @param loggedInUser The current user
     * @param crashId Crash ID
     * @return Crash notes for crash
     *
     * @xmlrpc.doc List crash notes for crash
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("int", "crashId")
     * @xmlrpc.returntype
     *     #array()
     *         #struct("crashNote")
     *             #prop("int", "id")
     *             #prop("string", "subject")
     *             #prop("string", "details")
     *             #prop("string", "updated")
     *         #struct_end()
     *     #array_end()
     */
    public List getCrashNotesForCrash(User loggedInUser, Integer crashId) {
        Crash c = CrashManager.lookupCrashByUserAndId(loggedInUser, crashId.longValue());
        List returnList = new ArrayList();
        for (CrashNote cn : c.getCrashNotes()) {
            Map crashNotesMap = new HashMap();
            crashNotesMap.put("id", cn.getId());
            crashNotesMap.put("subject", cn.getSubject());
            crashNotesMap.put("details", cn.getNote() == null ? "" : cn.getNote());
            crashNotesMap.put("updated", cn.getModifiedString());
            returnList.add(crashNotesMap);
        }
        return returnList;
    }

    /**
     * @param loggedInUser The current user
     * @return Software Crash Overview
     *
     * @xmlrpc.doc Get Software Crash Overview
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.returntype
     *     #array()
     *         #struct("crash")
     *             #prop_desc("string", "uuid", "Crash UUID")
     *             #prop_desc("string", "component",
     *                        "Package component (set if unique and non empty)")
     *             #prop_desc("int", "crash_count", "Number of crashes occurred")
     *             #prop_desc("int", "system_count", "Number of systems affected")
     *             #prop_desc("dateTime.iso8601", "last_report", "Last crash occurence")
     *         #struct_end()
     *     #array_end()
     */
    public List getCrashOverview(User loggedInUser) {
        List returnList = new ArrayList();
        for (IdenticalCrashesDto ic : CrashFactory.listIdenticalCrashesForOrg(loggedInUser,
                loggedInUser.getOrg())) {
            Map crashMap = new HashMap();
            crashMap.put("uuid", ic.getUuid());
            String component = ic.getComponent();
            if (component != null) {
                crashMap.put("component", component);
            }
            crashMap.put("crash_count", ic.getTotalCrashCount());
            crashMap.put("system_count", ic.getSystemCount());
            crashMap.put("last_report", ic.getLastCrashReport());
            returnList.add(crashMap);
        }
        return returnList;
    }

    /**
     * @param loggedInUser The current user
     * @param uuid Crash UUID to search for
     * @return List of crashes with given UUID
     *
     * @xmlrpc.doc List software crashes with given UUID
     * @xmlrpc.param #param("string", "sessionKey")
     * @xmlrpc.param #param("string", "uuid")
     * @xmlrpc.returntype
     *     #array()
     *         #struct("crash")
     *             #prop_desc("int", "server_id",
     *                        "ID of the server the crash occurred on")
     *             #prop_desc("string", "server_name",
     *                       "Name of the server the crash occurred on")
     *             #prop_desc("int", "crash_id", "ID of the crash with given UUID")
     *             #prop_desc("int", "crash_count",
     *                        "Number of times the crash with given UUID occurred")
     *             #prop_desc("string", "crash_component", "Crash component")
     *             #prop_desc("dateTime.iso8601", "last_report", "Last crash occurence")
     *         #struct_end()
     *     #array_end()
     */
    public List getCrashesByUuid(User loggedInUser, String uuid) {
        List returnList = new ArrayList();
        for (CrashSystemsDto cs : CrashFactory.listCrashSystems(loggedInUser, loggedInUser.getOrg(), uuid)) {
            Map crashMap = new HashMap();
            crashMap.put("server_id", cs.getServerId());
            crashMap.put("server_name", cs.getServerName());
            crashMap.put("crash_id", cs.getCrashId());
            crashMap.put("crash_count", cs.getCrashCount());
            crashMap.put("crash_component", cs.getCrashComponent());
            crashMap.put("last_report", cs.getLastReport());
            returnList.add(crashMap);
        }
        return returnList;
    }
}