com.ethercamp.harmony.web.controller.WebSocketController.java Source code

Java tutorial

Introduction

Here is the source code for com.ethercamp.harmony.web.controller.WebSocketController.java

Source

/*
 * Copyright 2015, 2016 Ether.Camp Inc. (US)
 * This file is part of Ethereum Harmony.
 *
 * Ethereum Harmony is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Ethereum Harmony is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Ethereum Harmony.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.ethercamp.harmony.web.controller;

import com.ethercamp.harmony.dto.*;
import com.ethercamp.harmony.service.BlockchainInfoService;
import com.ethercamp.harmony.util.AppConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

@Controller
public class WebSocketController {

    @Autowired
    BlockchainInfoService blockchainInfoService;

    @Autowired
    private Environment env;

    /**
     * Websocket handlers for immediate result.
     */

    @MessageMapping("/machineInfo")
    public MachineInfoDTO getMachineInfo() {
        return blockchainInfoService.getMachineInfo();
    }

    @MessageMapping("/initialInfo")
    public InitialInfoDTO getInitialInfo() {
        return blockchainInfoService.getInitialInfo();
    }

    @MessageMapping("/currentBlocks")
    public Queue<BlockInfo> getBlocks() {
        return blockchainInfoService.getBlocks();
    }

    @MessageMapping("/currentSystemLogs")
    public Queue<String> getSystemLogs() {
        return blockchainInfoService.getSystemLogs();
    }

    /**
     * Defines request mapping for all site pages.
     * As we have angular routing - we return index.html here.
     */
    @RequestMapping({ "/", "/systemLog", "/peers", "/rpcUsage", "/terminal", "/wallet", "/contracts",
            "/contractNew" })
    public String index(HttpServletRequest request) {
        final boolean contractsEnabled = env.getProperty("feature.contract.enabled", "false")
                .equalsIgnoreCase("true");
        if (!contractsEnabled && request.getRequestURI().equalsIgnoreCase("/contracts")) {
            return "error.html";
        }
        return "index.html";
    }

    /**
     * Also handles JSON-RPC requests at site root
     */
    @RequestMapping(value = { AppConst.JSON_RPC_ALIAS_PATH }, method = RequestMethod.POST)
    public String jsonrpcAlias() {
        return "forward:" + AppConst.JSON_RPC_PATH;
    }

    /**
     * @return logs file to be able to download from browser
     */
    @RequestMapping(value = "/logs/{logName:.+}", method = RequestMethod.GET)
    @ResponseBody
    public FileSystemResource logFile(@PathVariable("logName") String logName, HttpServletResponse response) {
        final String fileName = logName;

        if (!fileName.endsWith(".log") && !fileName.endsWith(".zip")) {
            throw new RuntimeException("Forbidden file requested: " + fileName);
        }

        // force file downloading, otherwise line breaks will gone in web view
        response.setContentType("text/plain");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

        return new FileSystemResource(new File(getLogsDir() + "/" + fileName));
    }

    @RequestMapping(value = "/logs", method = RequestMethod.GET)
    @ResponseBody
    public String listLogFiles() {
        final File logsLocation = new File(getLogsDir());
        final File[] files = logsLocation.listFiles();
        if (files == null) {
            return "No logs found";
        }

        return "<html><body>"
                + Arrays.asList(files).stream().sorted()
                        .map(f -> "<a href='logs/" + f.getName() + "'>" + f.getName() + "</a> "
                                + readableFileSize(f.length()))
                        .collect(Collectors.joining("<br>"))

                + "</body></html>";
    }

    private String getLogsDir() {
        return env.getProperty("logs.dir", "logs");
    }

    @RequestMapping(value = "/config", method = RequestMethod.GET)
    @ResponseBody
    public String showConfig() {
        return blockchainInfoService.getConfigDump().replaceAll("\n", "<br>");
    }

    @RequestMapping(value = "/genesis", method = RequestMethod.GET)
    @ResponseBody
    public String showGenesis() {
        return blockchainInfoService.getGenesisDump().replaceAll("\n", "<br>");
    }

    // for human readable size
    private String readableFileSize(long size) {
        if (size <= 0)
            return "0";
        final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }
}