com.coinblesk.server.controller.AdminController.java Source code

Java tutorial

Introduction

Here is the source code for com.coinblesk.server.controller.AdminController.java

Source

/*
 * Copyright 2016 The Coinblesk team and the CSG Group at University of Zurich
 *
 * Licensed 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 com.coinblesk.server.controller;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

import java.time.Instant;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import javax.servlet.ServletContext;

import com.coinblesk.server.config.AppConfig;
import com.coinblesk.server.dto.KeysDTO;
import com.coinblesk.server.dto.TimeLockedAddressDTO;
import com.coinblesk.server.entity.Keys;
import com.coinblesk.server.service.KeyService;
import com.coinblesk.util.SerializeUtils;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.params.TestNet3Params;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.coinblesk.server.service.WalletService;
import com.coinblesk.server.utils.ApiVersion;
import com.coinblesk.util.Pair;

/**
 *
 * @author Thomas Bocek
 * @author Andreas Albrecht
 * @author Sebastian Stephan
 */

@Controller
@RequestMapping(value = "/admin")
public class AdminController {

    private static Logger LOG = LoggerFactory.getLogger(AdminController.class);

    private final AppConfig appConfig;

    private final WalletService walletService;

    private final KeyService keyService;

    @Autowired
    public AdminController(AppConfig appConfig, WalletService walletService, KeyService keyService) {
        this.appConfig = appConfig;
        this.walletService = walletService;
        this.keyService = keyService;
    }

    @RequestMapping(value = "/balance", method = GET)
    @ResponseBody
    public Coin balance() {
        return walletService.getBalance();
    }

    @RequestMapping(value = "/addresses", method = GET)
    @ResponseBody
    public Map<Address, Coin> addresses() {
        Map<Address, Coin> addressBalances = walletService.getBalanceByAddresses();
        LOG.debug("Total addresses: " + addressBalances.size());
        return addressBalances;
    }

    @RequestMapping(value = "/utxo", method = GET)
    @ResponseBody
    public List<Pair<String, String>> utxo() {
        // cannot return utxo due to GSON recursion
        List<TransactionOutput> utxo = walletService.getUnspentOutputs();
        List<Pair<String, String>> txOuts = new ArrayList<>();
        for (TransactionOutput txOut : utxo) {
            txOuts.add(new Pair<>(txOut.getOutPointFor().toString(), txOut.toString()));
        }
        return txOuts;
    }

    @RequestMapping(value = "/keys", method = GET)
    @ResponseBody
    public List<KeysDTO> getAllKeys() {
        NetworkParameters params = appConfig.getNetworkParameters();

        // Pre-calculate balances for each address
        Map<Address, Coin> balances = walletService.getBalanceByAddresses();

        List<Keys> keys = keyService.allKeys();

        // ...and summed for each public key
        Map<Keys, Long> balancesPerKeys = keys.stream()
                .collect(Collectors.toMap(Function.identity(), key -> key.timeLockedAddresses().stream()
                        .map(tla -> tla.toAddress(params)).map(balances::get).mapToLong(Coin::longValue).sum()));

        // Map the Keys entities to DTOs including the containing TimeLockedAddresses
        return keys.stream().map(key -> new KeysDTO(SerializeUtils.bytesToHex(key.clientPublicKey()),
                SerializeUtils.bytesToHex(key.serverPublicKey()), SerializeUtils.bytesToHex(key.serverPrivateKey()),
                Date.from(Instant.ofEpochSecond(key.timeCreated())), key.virtualBalance(), balancesPerKeys.get(key),
                key.virtualBalance() + balancesPerKeys.get(key), key.timeLockedAddresses().stream().map(tla -> {
                    Instant createdAt = Instant.ofEpochSecond(tla.getTimeCreated());
                    Instant lockedUntil = Instant.ofEpochSecond(tla.getLockTime());
                    Coin balance = balances.get(tla.toAddress(params));
                    return new TimeLockedAddressDTO(tla.toAddress(params).toString(),
                            "http://" + (params.getClass().equals(TestNet3Params.class) ? "tbtc." : "")
                                    + "blockr.io/address/info/" + tla.toAddress(params),
                            Date.from(createdAt), Date.from(lockedUntil), lockedUntil.isAfter(Instant.now()),
                            balance.longValue());
                }).collect(Collectors.toList()))).collect(Collectors.toList());
    }
}