restructure project

This commit is contained in:
Carsten Otto
2021-11-22 20:24:13 +01:00
parent a82cb13ef7
commit 874e8fffa6
55 changed files with 46 additions and 14 deletions

View File

@@ -0,0 +1,10 @@
package de.cotto.lndmanagej;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootConfiguration {
public SpringBootConfiguration() {
// default constructor
}
}

View File

@@ -0,0 +1,89 @@
package de.cotto.lndmanagej.controller;
import de.cotto.lndmanagej.metrics.Metrics;
import de.cotto.lndmanagej.model.Coins;
import de.cotto.lndmanagej.service.BalanceService;
import de.cotto.lndmanagej.service.ChannelService;
import de.cotto.lndmanagej.service.NodeService;
import de.cotto.lndmanagej.service.OnChainCostService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Optional;
import static de.cotto.lndmanagej.model.BalanceInformationFixtures.BALANCE_INFORMATION_2;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID;
import static de.cotto.lndmanagej.model.ChannelPointFixtures.CHANNEL_POINT;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_PRIVATE;
import static de.cotto.lndmanagej.model.NodeFixtures.ALIAS_2;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(controllers = ChannelDetailsController.class)
class ChannelDetailsControllerIT {
private static final String CHANNEL_PREFIX = "/api/channel/" + CHANNEL_ID.getShortChannelId();
@Autowired
private MockMvc mockMvc;
@MockBean
private ChannelService channelService;
@MockBean
private NodeService nodeService;
@MockBean
@SuppressWarnings("unused")
private Metrics metrics;
@MockBean
private OnChainCostService onChainCostService;
@MockBean
private BalanceService balanceService;
@Test
void not_found() throws Exception {
mockMvc.perform(get(CHANNEL_PREFIX + "/details"))
.andExpect(status().isNotFound());
}
@Test
void getChannelDetails() throws Exception {
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
when(channelService.getLocalChannel(CHANNEL_ID)).thenReturn(Optional.of(LOCAL_OPEN_CHANNEL_PRIVATE));
when(onChainCostService.getOpenCosts(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(1000)));
when(onChainCostService.getCloseCosts(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(2000)));
when(balanceService.getBalanceInformation(CHANNEL_ID)).thenReturn(Optional.of(BALANCE_INFORMATION_2));
mockMvc.perform(get(CHANNEL_PREFIX + "/details"))
.andExpect(jsonPath("$.channelIdShort", is(String.valueOf(CHANNEL_ID.getShortChannelId()))))
.andExpect(jsonPath("$.channelIdCompact", is(CHANNEL_ID.getCompactForm())))
.andExpect(jsonPath("$.channelIdCompactLnd", is(CHANNEL_ID.getCompactFormLnd())))
.andExpect(jsonPath("$.channelPoint", is(CHANNEL_POINT.toString())))
.andExpect(jsonPath("$.remotePubkey", is(PUBKEY_2.toString())))
.andExpect(jsonPath("$.remoteAlias", is(ALIAS_2)))
.andExpect(jsonPath("$.private", is(true)))
.andExpect(jsonPath("$.onChainCosts.openCosts", is("1000")))
.andExpect(jsonPath("$.onChainCosts.closeCosts", is("2000")))
.andExpect(jsonPath("$.balance.localBalance", is("2000")))
.andExpect(jsonPath("$.balance.localReserve", is("200")))
.andExpect(jsonPath("$.balance.localAvailable", is("1800")))
.andExpect(jsonPath("$.balance.remoteBalance", is("223")))
.andExpect(jsonPath("$.balance.remoteReserve", is("20")))
.andExpect(jsonPath("$.balance.remoteAvailable", is("203")));
}
@Test
void getChannelDetails_channel_not_found() throws Exception {
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
mockMvc.perform(get(CHANNEL_PREFIX + "/details"))
.andExpect(status().isNotFound());
}
}

View File

@@ -0,0 +1,163 @@
package de.cotto.lndmanagej.controller;
import de.cotto.lndmanagej.metrics.Metrics;
import de.cotto.lndmanagej.model.Coins;
import de.cotto.lndmanagej.service.BalanceService;
import de.cotto.lndmanagej.service.ChannelService;
import de.cotto.lndmanagej.service.FeeService;
import de.cotto.lndmanagej.service.NodeService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Set;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_3;
import static de.cotto.lndmanagej.model.CoopClosedChannelFixtures.CLOSED_CHANNEL;
import static de.cotto.lndmanagej.model.CoopClosedChannelFixtures.CLOSED_CHANNEL_3;
import static de.cotto.lndmanagej.model.ForceClosingChannelFixtures.FORCE_CLOSING_CHANNEL;
import static de.cotto.lndmanagej.model.ForceClosingChannelFixtures.FORCE_CLOSING_CHANNEL_3;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_3;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_TO_NODE_3;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_3;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(controllers = LegacyController.class)
class LegacyControllerIT {
private static final String PUBKEY_BASE = "/legacy/node/" + PUBKEY;
private static final String CHANNEL_BASE = "/legacy/channel/" + CHANNEL_ID;
private static final long FEE_RATE = 123L;
private static final Coins BASE_FEE = Coins.ofMilliSatoshis(10L);
@Autowired
private MockMvc mockMvc;
@MockBean
@SuppressWarnings("unused")
private NodeService nodeService;
@MockBean
private ChannelService channelService;
@MockBean
private FeeService feeService;
@MockBean
private BalanceService balanceService;
@MockBean
@SuppressWarnings("unused")
private Metrics metrics;
@Test
void getAllChannelIds_for_peer() throws Exception {
when(channelService.getAllChannelsWith(PUBKEY)).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, CLOSED_CHANNEL_3));
mockMvc.perform(get(PUBKEY_BASE + "/all-channels"))
.andExpect(content().string(CHANNEL_ID + "\n" + CHANNEL_ID_3));
}
@Test
void getOpenChannelIds() throws Exception {
when(channelService.getOpenChannels()).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_3));
mockMvc.perform(get("/legacy/open-channels"))
.andExpect(content().string(CHANNEL_ID + "\n" + CHANNEL_ID_3));
}
@Test
void getOpenChannelIdsPretty() throws Exception {
when(channelService.getOpenChannels()).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_3));
mockMvc.perform(get("/legacy/open-channels/pretty"))
.andExpect(status().isOk());
}
@Test
void getClosedChannelIds() throws Exception {
when(channelService.getClosedChannels()).thenReturn(Set.of(CLOSED_CHANNEL, CLOSED_CHANNEL_3));
mockMvc.perform(get("/legacy/closed-channels"))
.andExpect(content().string(CHANNEL_ID + "\n" + CHANNEL_ID_3));
}
@Test
void getForceClosingChannels() throws Exception {
when(channelService.getForceClosingChannels())
.thenReturn(Set.of(FORCE_CLOSING_CHANNEL, FORCE_CLOSING_CHANNEL_3));
mockMvc.perform(get("/legacy/force-closing-channels"))
.andExpect(content().string(CHANNEL_ID + "\n" + CHANNEL_ID_3));
}
@Test
void getPeerPubkeys() throws Exception {
when(channelService.getOpenChannels()).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_TO_NODE_3));
mockMvc.perform(get("/legacy/peer-pubkeys"))
.andExpect(content().string(PUBKEY_2 + "\n" + PUBKEY_3));
}
@Test
void getIncomingFeeRate() throws Exception {
when(feeService.getIncomingFeeRate(CHANNEL_ID)).thenReturn(FEE_RATE);
mockMvc.perform(get(CHANNEL_BASE + "/incoming-fee-rate"))
.andExpect(content().string(Long.toString(FEE_RATE)));
}
@Test
void getOutgoingFeeRate() throws Exception {
when(feeService.getOutgoingFeeRate(CHANNEL_ID)).thenReturn(FEE_RATE);
mockMvc.perform(get(CHANNEL_BASE + "/outgoing-fee-rate"))
.andExpect(content().string(Long.toString(FEE_RATE)));
}
@Test
void getIncomingBaseFee() throws Exception {
when(feeService.getIncomingBaseFee(CHANNEL_ID)).thenReturn(BASE_FEE);
mockMvc.perform(get(CHANNEL_BASE + "/incoming-base-fee"))
.andExpect(content().string(String.valueOf(BASE_FEE.milliSatoshis())));
}
@Test
void getOutgoingBaseFee() throws Exception {
when(feeService.getOutgoingBaseFee(CHANNEL_ID)).thenReturn(BASE_FEE);
mockMvc.perform(get(CHANNEL_BASE + "/outgoing-base-fee"))
.andExpect(content().string(String.valueOf(BASE_FEE.milliSatoshis())));
}
@Test
void getAvailableLocalBalance_channel() throws Exception {
Coins availableBalance = Coins.ofSatoshis(999);
when(balanceService.getAvailableLocalBalance(CHANNEL_ID)).thenReturn(availableBalance);
mockMvc.perform(get(CHANNEL_BASE + "/available-local-balance"))
.andExpect(content().string(String.valueOf(availableBalance.satoshis())));
}
@Test
void getAvailableRemoteBalance_channel() throws Exception {
Coins availableBalance = Coins.ofSatoshis(999);
when(balanceService.getAvailableRemoteBalance(CHANNEL_ID)).thenReturn(availableBalance);
mockMvc.perform(get(CHANNEL_BASE + "/available-remote-balance"))
.andExpect(content().string(String.valueOf(availableBalance.satoshis())));
}
@Test
void getAvailableLocalBalance_peer() throws Exception {
Coins availableBalance = Coins.ofSatoshis(999);
when(balanceService.getAvailableLocalBalance(PUBKEY)).thenReturn(availableBalance);
mockMvc.perform(get(PUBKEY_BASE + "/available-local-balance"))
.andExpect(content().string(String.valueOf(availableBalance.satoshis())));
}
@Test
void getAvailableRemoteBalance_peer() throws Exception {
Coins availableBalance = Coins.ofSatoshis(999);
when(balanceService.getAvailableRemoteBalance(PUBKEY)).thenReturn(availableBalance);
mockMvc.perform(get(PUBKEY_BASE + "/available-remote-balance"))
.andExpect(content().string(String.valueOf(availableBalance.satoshis())));
}
}

View File

@@ -0,0 +1,109 @@
package de.cotto.lndmanagej.controller;
import de.cotto.lndmanagej.metrics.Metrics;
import de.cotto.lndmanagej.model.Coins;
import de.cotto.lndmanagej.model.Node;
import de.cotto.lndmanagej.service.BalanceService;
import de.cotto.lndmanagej.service.ChannelService;
import de.cotto.lndmanagej.service.NodeService;
import de.cotto.lndmanagej.service.OnChainCostService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import java.util.Set;
import static de.cotto.lndmanagej.model.BalanceInformationFixtures.BALANCE_INFORMATION;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_2;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_3;
import static de.cotto.lndmanagej.model.CoopClosedChannelFixtures.CLOSED_CHANNEL;
import static de.cotto.lndmanagej.model.CoopClosedChannelFixtures.CLOSED_CHANNEL_3;
import static de.cotto.lndmanagej.model.ForceClosingChannelFixtures.FORCE_CLOSING_CHANNEL_2;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_2;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_3;
import static de.cotto.lndmanagej.model.NodeFixtures.ALIAS_2;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2;
import static de.cotto.lndmanagej.model.WaitingCloseChannelFixtures.WAITING_CLOSE_CHANNEL;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@WebMvcTest(controllers = NodeController.class)
class NodeControllerIT {
private static final String NODE_PREFIX = "/api/node/" + PUBKEY_2;
@Autowired
private MockMvc mockMvc;
@MockBean
private NodeService nodeService;
@MockBean
private ChannelService channelService;
@MockBean
private OnChainCostService onChainCostService;
@MockBean
private BalanceService balanceService;
@MockBean
@SuppressWarnings("unused")
private Metrics metrics;
@Test
void getAlias() throws Exception {
when(nodeService.getAlias(PUBKEY_2)).thenReturn(ALIAS_2);
mockMvc.perform(get(NODE_PREFIX + "/alias"))
.andExpect(content().string(ALIAS_2));
}
@Test
void getDetails() throws Exception {
when(nodeService.getNode(PUBKEY_2)).thenReturn(new Node(PUBKEY_2, ALIAS_2, 0, true));
when(channelService.getOpenChannelsWith(PUBKEY_2)).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_2));
when(channelService.getClosedChannelsWith(PUBKEY_2)).thenReturn(Set.of(CLOSED_CHANNEL, CLOSED_CHANNEL_3));
when(channelService.getWaitingCloseChannelsFor(PUBKEY_2)).thenReturn(Set.of(WAITING_CLOSE_CHANNEL));
when(channelService.getForceClosingChannelsFor(PUBKEY_2)).thenReturn(Set.of(FORCE_CLOSING_CHANNEL_2));
when(onChainCostService.getOpenCostsWith(PUBKEY_2)).thenReturn(Coins.ofSatoshis(123));
when(onChainCostService.getCloseCostsWith(PUBKEY_2)).thenReturn(Coins.ofSatoshis(456));
when(balanceService.getBalanceInformation(PUBKEY_2)).thenReturn(BALANCE_INFORMATION);
List<String> channelIds = List.of(CHANNEL_ID.toString(), CHANNEL_ID_2.toString());
List<String> closedChannelIds = List.of(CHANNEL_ID.toString(), CHANNEL_ID_3.toString());
List<String> waitingCloseChannelIds = List.of(CHANNEL_ID.toString());
List<String> forceClosingChannelIds = List.of(CHANNEL_ID_2.toString());
mockMvc.perform(get(NODE_PREFIX + "/details"))
.andExpect(jsonPath("$.node", is(PUBKEY_2.toString())))
.andExpect(jsonPath("$.alias", is(ALIAS_2)))
.andExpect(jsonPath("$.channels", is(channelIds)))
.andExpect(jsonPath("$.closedChannels", is(closedChannelIds)))
.andExpect(jsonPath("$.waitingCloseChannels", is(waitingCloseChannelIds)))
.andExpect(jsonPath("$.pendingForceClosingChannels", is(forceClosingChannelIds)))
.andExpect(jsonPath("$.onChainCosts.openCosts", is("123")))
.andExpect(jsonPath("$.onChainCosts.closeCosts", is("456")))
.andExpect(jsonPath("$.balance.localBalance", is("1000")))
.andExpect(jsonPath("$.balance.localReserve", is("100")))
.andExpect(jsonPath("$.balance.localAvailable", is("900")))
.andExpect(jsonPath("$.balance.remoteBalance", is("123")))
.andExpect(jsonPath("$.balance.remoteReserve", is("10")))
.andExpect(jsonPath("$.balance.remoteAvailable", is("113")))
.andExpect(jsonPath("$.online", is(true)));
}
@Test
void getOpenChannelIds_for_peer() throws Exception {
when(channelService.getOpenChannelsWith(PUBKEY_2)).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_3));
List<String> channelIds = List.of(CHANNEL_ID.toString(), CHANNEL_ID_3.toString());
mockMvc.perform(get(NODE_PREFIX + "/open-channels"))
.andExpect(jsonPath("$.node", is(PUBKEY_2.toString())))
.andExpect(jsonPath("$.channels", is(channelIds)));
}
}

View File

@@ -0,0 +1,74 @@
package de.cotto.lndmanagej.controller;
import de.cotto.lndmanagej.metrics.Metrics;
import de.cotto.lndmanagej.model.Coins;
import de.cotto.lndmanagej.service.OnChainCostService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Optional;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(controllers = OnChainCostsController.class)
class OnChainCostsControllerIT {
private static final String CHANNEL_PREFIX = "/api/channel/" + CHANNEL_ID.getShortChannelId();
private static final String PEER_PREFIX = "/api/node/" + PUBKEY;
@Autowired
private MockMvc mockMvc;
@MockBean
private OnChainCostService onChainCostService;
@MockBean
@SuppressWarnings("unused")
private Metrics metrics;
@Test
void on_chain_costs_for_peer() throws Exception {
when(onChainCostService.getOpenCostsWith(PUBKEY)).thenReturn(Coins.ofSatoshis(123));
when(onChainCostService.getCloseCostsWith(PUBKEY)).thenReturn(Coins.ofSatoshis(456));
mockMvc.perform(get(PEER_PREFIX + "/on-chain-costs"))
.andExpect(jsonPath("$.openCosts", is("123")))
.andExpect(jsonPath("$.closeCosts", is("456")));
}
@Test
void open_costs_for_channel() throws Exception {
when(onChainCostService.getOpenCosts(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(123)));
mockMvc.perform(get(CHANNEL_PREFIX + "/open-costs"))
.andExpect(content().string("123"));
}
@Test
void open_costs_for_channel_unknown() throws Exception {
mockMvc.perform(get(CHANNEL_PREFIX + "/open-costs"))
.andExpect(status().isBadRequest())
.andExpect(content().string("Unable to get open costs for channel with ID " + CHANNEL_ID));
}
@Test
void close_costs_for_channel() throws Exception {
when(onChainCostService.getCloseCosts(CHANNEL_ID)).thenReturn(Optional.of(Coins.ofSatoshis(123)));
mockMvc.perform(get(CHANNEL_PREFIX + "/close-costs"))
.andExpect(content().string("123"));
}
@Test
void close_costs_for_channel_unknown() throws Exception {
mockMvc.perform(get(CHANNEL_PREFIX + "/close-costs"))
.andExpect(status().isBadRequest())
.andExpect(content().string("Unable to get close costs for channel with ID " + CHANNEL_ID));
}
}

View File

@@ -0,0 +1,35 @@
package de.cotto.lndmanagej.controller;
import de.cotto.lndmanagej.metrics.Metrics;
import de.cotto.lndmanagej.service.OwnNodeService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
@WebMvcTest(controllers = StatusController.class)
class StatusControllerIT {
private static final String PREFIX = "/api/status/";
@Autowired
private MockMvc mockMvc;
@MockBean
@SuppressWarnings("unused")
private Metrics metrics;
@MockBean
private OwnNodeService ownNodeService;
@Test
void isSyncedToChain() throws Exception {
when(ownNodeService.isSyncedToChain()).thenReturn(true);
mockMvc.perform(get(PREFIX + "/synced-to-chain"))
.andExpect(content().string("true"));
}
}