From de40c32f63f3d08b2d2ab954bca6db357fb3e5fe Mon Sep 17 00:00:00 2001 From: Carsten Otto Date: Mon, 27 Dec 2021 20:18:05 +0100 Subject: [PATCH] add node warnings functionality (at the moment: only online percentage) --- .../service/NodeDetailsService.java | 14 +++++- .../service/NodeWarningsService.java | 40 ++++++++++++++++ .../service/NodeDetailsServiceTest.java | 7 +++ .../service/NodeWarningsServiceTest.java | 40 ++++++++++++++++ .../cotto/lndmanagej/model/NodeDetails.java | 3 +- .../model/NodeOnlinePercentageWarning.java | 4 ++ .../cotto/lndmanagej/model/NodeWarning.java | 4 ++ .../cotto/lndmanagej/model/NodeWarnings.java | 12 +++++ .../NodeOnlinePercentageWarningTest.java | 13 +++++ .../lndmanagej/model/NodeWarningsTest.java | 21 +++++++++ .../lndmanagej/model/NodeDetailsFixtures.java | 7 ++- .../lndmanagej/model/NodeWarningFixtures.java | 6 +++ .../model/NodeWarningsFixtures.java | 9 ++++ .../controller/NodeControllerIT.java | 1 + .../controller/WarningsControllerIT.java | 47 +++++++++++++++++++ .../controller/WarningsController.java | 30 ++++++++++++ .../controller/dto/NodeDetailsDto.java | 7 ++- .../controller/dto/NodeWarningsDto.java | 12 +++++ .../controller/WarningsControllerTest.java | 30 ++++++++++++ .../controller/dto/NodeDetailsDtoTest.java | 4 +- .../controller/dto/NodeWarningsDtoTest.java | 14 ++++++ 21 files changed, 317 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/de/cotto/lndmanagej/service/NodeWarningsService.java create mode 100644 backend/src/test/java/de/cotto/lndmanagej/service/NodeWarningsServiceTest.java create mode 100644 model/src/main/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarning.java create mode 100644 model/src/main/java/de/cotto/lndmanagej/model/NodeWarning.java create mode 100644 model/src/main/java/de/cotto/lndmanagej/model/NodeWarnings.java create mode 100644 model/src/test/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarningTest.java create mode 100644 model/src/test/java/de/cotto/lndmanagej/model/NodeWarningsTest.java create mode 100644 model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningFixtures.java create mode 100644 model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningsFixtures.java create mode 100644 web/src/integrationTest/java/de/cotto/lndmanagej/controller/WarningsControllerIT.java create mode 100644 web/src/main/java/de/cotto/lndmanagej/controller/WarningsController.java create mode 100644 web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDto.java create mode 100644 web/src/test/java/de/cotto/lndmanagej/controller/WarningsControllerTest.java create mode 100644 web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDtoTest.java diff --git a/backend/src/main/java/de/cotto/lndmanagej/service/NodeDetailsService.java b/backend/src/main/java/de/cotto/lndmanagej/service/NodeDetailsService.java index 7dac7bf0..e40b8fe7 100644 --- a/backend/src/main/java/de/cotto/lndmanagej/service/NodeDetailsService.java +++ b/backend/src/main/java/de/cotto/lndmanagej/service/NodeDetailsService.java @@ -6,6 +6,7 @@ import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.FeeReport; import de.cotto.lndmanagej.model.Node; import de.cotto.lndmanagej.model.NodeDetails; +import de.cotto.lndmanagej.model.NodeWarnings; import de.cotto.lndmanagej.model.OnChainCosts; import de.cotto.lndmanagej.model.OnlineReport; import de.cotto.lndmanagej.model.Pubkey; @@ -26,6 +27,7 @@ public class NodeDetailsService { private final FeeService feeService; private final RebalanceService rebalanceService; private final OnlinePeersService onlinePeersService; + private final NodeWarningsService warningsService; public NodeDetailsService( ChannelService channelService, @@ -34,7 +36,8 @@ public class NodeDetailsService { BalanceService balanceService, FeeService feeService, RebalanceService rebalanceService, - OnlinePeersService onlinePeersService + OnlinePeersService onlinePeersService, + NodeWarningsService warningsService ) { this.channelService = channelService; this.nodeService = nodeService; @@ -43,6 +46,7 @@ public class NodeDetailsService { this.feeService = feeService; this.rebalanceService = rebalanceService; this.onlinePeersService = onlinePeersService; + this.warningsService = warningsService; } public NodeDetails getDetails(Pubkey pubkey) { @@ -52,6 +56,7 @@ public class NodeDetailsService { CompletableFuture balanceInformation = getBalanceInformation(pubkey); CompletableFuture feeReport = getFeeReport(pubkey); CompletableFuture rebalanceReport = getRebalanceReport(pubkey); + CompletableFuture nodeWarnings = getNodeWarnings(pubkey); List openChannelIds = getSortedChannelIds(channelService.getOpenChannelsWith(pubkey)); List closedChannelIds = @@ -72,7 +77,8 @@ public class NodeDetailsService { balanceInformation.get(), onlineReport.get(), feeReport.get(), - rebalanceReport.get() + rebalanceReport.get(), + nodeWarnings.get() ); } catch (InterruptedException | ExecutionException exception) { throw new IllegalStateException("Unable to compute node details for " + pubkey, exception); @@ -95,6 +101,10 @@ public class NodeDetailsService { return CompletableFuture.supplyAsync(() -> rebalanceService.getReportForPeer(pubkey)); } + private CompletableFuture getNodeWarnings(Pubkey pubkey) { + return CompletableFuture.supplyAsync(() -> warningsService.getNodeWarnings(pubkey)); + } + private CompletableFuture getBalanceInformation(Pubkey pubkey) { return CompletableFuture.supplyAsync(() -> balanceService.getBalanceInformationForPeer(pubkey)); } diff --git a/backend/src/main/java/de/cotto/lndmanagej/service/NodeWarningsService.java b/backend/src/main/java/de/cotto/lndmanagej/service/NodeWarningsService.java new file mode 100644 index 00000000..b916a19a --- /dev/null +++ b/backend/src/main/java/de/cotto/lndmanagej/service/NodeWarningsService.java @@ -0,0 +1,40 @@ +package de.cotto.lndmanagej.service; + +import de.cotto.lndmanagej.model.NodeOnlinePercentageWarning; +import de.cotto.lndmanagej.model.NodeWarning; +import de.cotto.lndmanagej.model.NodeWarnings; +import de.cotto.lndmanagej.model.Pubkey; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +@Component +public class NodeWarningsService { + private static final int THRESHOLD = 80; + + private final OnlinePeersService onlinePeersService; + + public NodeWarningsService(OnlinePeersService onlinePeersService) { + this.onlinePeersService = onlinePeersService; + } + + public NodeWarnings getNodeWarnings(Pubkey pubkey) { + List warnings = Stream.of((Function>) this::getOnlineWarning) + .map(function -> function.apply(pubkey)) + .flatMap(Optional::stream) + .toList(); + return new NodeWarnings(warnings); + } + + private Optional getOnlineWarning(Pubkey pubkey) { + int percentage = onlinePeersService.getOnlinePercentageLastWeek(pubkey); + if (percentage < THRESHOLD) { + return Optional.of(new NodeOnlinePercentageWarning(percentage)); + } + return Optional.empty(); + } + +} diff --git a/backend/src/test/java/de/cotto/lndmanagej/service/NodeDetailsServiceTest.java b/backend/src/test/java/de/cotto/lndmanagej/service/NodeDetailsServiceTest.java index b35410b3..ef59cc03 100644 --- a/backend/src/test/java/de/cotto/lndmanagej/service/NodeDetailsServiceTest.java +++ b/backend/src/test/java/de/cotto/lndmanagej/service/NodeDetailsServiceTest.java @@ -2,6 +2,7 @@ package de.cotto.lndmanagej.service; import de.cotto.lndmanagej.model.BalanceInformation; import de.cotto.lndmanagej.model.FeeReport; +import de.cotto.lndmanagej.model.NodeWarnings; import de.cotto.lndmanagej.model.OnChainCosts; import de.cotto.lndmanagej.model.RebalanceReport; import org.junit.jupiter.api.Test; @@ -21,6 +22,7 @@ import static de.cotto.lndmanagej.model.NodeDetailsFixtures.NODE_DETAILS; import static de.cotto.lndmanagej.model.NodeDetailsFixtures.NODE_DETAILS_EMPTY; import static de.cotto.lndmanagej.model.NodeFixtures.NODE; import static de.cotto.lndmanagej.model.NodeFixtures.NODE_PEER; +import static de.cotto.lndmanagej.model.NodeWarningsFixtures.NODE_WARNINGS; import static de.cotto.lndmanagej.model.OnChainCostsFixtures.ON_CHAIN_COSTS; import static de.cotto.lndmanagej.model.OnlineReportFixtures.ONLINE_REPORT; import static de.cotto.lndmanagej.model.OnlineReportFixtures.ONLINE_REPORT_OFFLINE; @@ -56,6 +58,9 @@ class NodeDetailsServiceTest { @Mock private OnlinePeersService onlinePeersService; + @Mock + private NodeWarningsService nodeWarningsService; + @Test void getDetails_no_channel() { when(nodeService.getNode(PUBKEY)).thenReturn(NODE); @@ -64,6 +69,7 @@ class NodeDetailsServiceTest { when(feeService.getFeeReportForPeer(PUBKEY)).thenReturn(FeeReport.EMPTY); when(rebalanceService.getReportForPeer(PUBKEY)).thenReturn(RebalanceReport.EMPTY); when(onlinePeersService.getOnlineReport(NODE_PEER)).thenReturn(ONLINE_REPORT_OFFLINE); + when(nodeWarningsService.getNodeWarnings(PUBKEY)).thenReturn(NodeWarnings.NONE); assertThat(nodeDetailsService.getDetails(PUBKEY)).isEqualTo(NODE_DETAILS_EMPTY); } @@ -79,6 +85,7 @@ class NodeDetailsServiceTest { when(feeService.getFeeReportForPeer(PUBKEY)).thenReturn(FEE_REPORT); when(rebalanceService.getReportForPeer(PUBKEY)).thenReturn(REBALANCE_REPORT); when(onlinePeersService.getOnlineReport(NODE_PEER)).thenReturn(ONLINE_REPORT); + when(nodeWarningsService.getNodeWarnings(PUBKEY)).thenReturn(NODE_WARNINGS); assertThat(nodeDetailsService.getDetails(PUBKEY)).isEqualTo(NODE_DETAILS); } } \ No newline at end of file diff --git a/backend/src/test/java/de/cotto/lndmanagej/service/NodeWarningsServiceTest.java b/backend/src/test/java/de/cotto/lndmanagej/service/NodeWarningsServiceTest.java new file mode 100644 index 00000000..9a8d03af --- /dev/null +++ b/backend/src/test/java/de/cotto/lndmanagej/service/NodeWarningsServiceTest.java @@ -0,0 +1,40 @@ +package de.cotto.lndmanagej.service; + +import de.cotto.lndmanagej.model.NodeOnlinePercentageWarning; +import de.cotto.lndmanagej.model.NodeWarnings; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class NodeWarningsServiceTest { + @InjectMocks + private NodeWarningsService nodeWarningsService; + + @Mock + private OnlinePeersService onlinePeersService; + + @BeforeEach + void setUp() { + when(onlinePeersService.getOnlinePercentageLastWeek(PUBKEY)).thenReturn(80); + } + + @Test + void getNodeWarnings_online_below_threshold() { + when(onlinePeersService.getOnlinePercentageLastWeek(PUBKEY)).thenReturn(79); + assertThat(nodeWarningsService.getNodeWarnings(PUBKEY)) + .isEqualTo(new NodeWarnings(new NodeOnlinePercentageWarning(79))); + } + + @Test + void getNodeWarnings_ok() { + assertThat(nodeWarningsService.getNodeWarnings(PUBKEY)).isEqualTo(NodeWarnings.NONE); + } +} \ No newline at end of file diff --git a/model/src/main/java/de/cotto/lndmanagej/model/NodeDetails.java b/model/src/main/java/de/cotto/lndmanagej/model/NodeDetails.java index 20f90b73..f9acce56 100644 --- a/model/src/main/java/de/cotto/lndmanagej/model/NodeDetails.java +++ b/model/src/main/java/de/cotto/lndmanagej/model/NodeDetails.java @@ -13,6 +13,7 @@ public record NodeDetails( BalanceInformation balanceInformation, OnlineReport onlineReport, FeeReport feeReport, - RebalanceReport rebalanceReport + RebalanceReport rebalanceReport, + NodeWarnings nodeWarnings ) { } diff --git a/model/src/main/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarning.java b/model/src/main/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarning.java new file mode 100644 index 00000000..d1e7f051 --- /dev/null +++ b/model/src/main/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarning.java @@ -0,0 +1,4 @@ +package de.cotto.lndmanagej.model; + +public record NodeOnlinePercentageWarning(int onlinePercentage) implements NodeWarning { +} diff --git a/model/src/main/java/de/cotto/lndmanagej/model/NodeWarning.java b/model/src/main/java/de/cotto/lndmanagej/model/NodeWarning.java new file mode 100644 index 00000000..5457af97 --- /dev/null +++ b/model/src/main/java/de/cotto/lndmanagej/model/NodeWarning.java @@ -0,0 +1,4 @@ +package de.cotto.lndmanagej.model; + +public interface NodeWarning { +} diff --git a/model/src/main/java/de/cotto/lndmanagej/model/NodeWarnings.java b/model/src/main/java/de/cotto/lndmanagej/model/NodeWarnings.java new file mode 100644 index 00000000..55f80fbd --- /dev/null +++ b/model/src/main/java/de/cotto/lndmanagej/model/NodeWarnings.java @@ -0,0 +1,12 @@ +package de.cotto.lndmanagej.model; + +import java.util.Arrays; +import java.util.List; + +public record NodeWarnings(List warnings) { + public static final NodeWarnings NONE = new NodeWarnings(); + + public NodeWarnings(NodeWarning... nodeWarnings) { + this(Arrays.stream(nodeWarnings).toList()); + } +} diff --git a/model/src/test/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarningTest.java b/model/src/test/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarningTest.java new file mode 100644 index 00000000..70f90f21 --- /dev/null +++ b/model/src/test/java/de/cotto/lndmanagej/model/NodeOnlinePercentageWarningTest.java @@ -0,0 +1,13 @@ +package de.cotto.lndmanagej.model; + +import org.junit.jupiter.api.Test; + +import static de.cotto.lndmanagej.model.NodeWarningFixtures.NODE_ONLINE_PERCENTAGE_WARNING; +import static org.assertj.core.api.Assertions.assertThat; + +class NodeOnlinePercentageWarningTest { + @Test + void onlinePercentage() { + assertThat(NODE_ONLINE_PERCENTAGE_WARNING.onlinePercentage()).isEqualTo(51); + } +} \ No newline at end of file diff --git a/model/src/test/java/de/cotto/lndmanagej/model/NodeWarningsTest.java b/model/src/test/java/de/cotto/lndmanagej/model/NodeWarningsTest.java new file mode 100644 index 00000000..8f5484cc --- /dev/null +++ b/model/src/test/java/de/cotto/lndmanagej/model/NodeWarningsTest.java @@ -0,0 +1,21 @@ +package de.cotto.lndmanagej.model; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static de.cotto.lndmanagej.model.NodeWarningFixtures.NODE_ONLINE_PERCENTAGE_WARNING; +import static de.cotto.lndmanagej.model.NodeWarningsFixtures.NODE_WARNINGS; +import static org.assertj.core.api.Assertions.assertThat; + +class NodeWarningsTest { + @Test + void warnings() { + assertThat(NODE_WARNINGS.warnings()).containsExactly(NODE_ONLINE_PERCENTAGE_WARNING); + } + + @Test + void none() { + assertThat(NodeWarnings.NONE).isEqualTo(new NodeWarnings(List.of())); + } +} \ No newline at end of file diff --git a/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeDetailsFixtures.java b/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeDetailsFixtures.java index 6afc0466..84160659 100644 --- a/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeDetailsFixtures.java +++ b/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeDetailsFixtures.java @@ -9,6 +9,7 @@ import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_3; import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_4; import static de.cotto.lndmanagej.model.FeeReportFixtures.FEE_REPORT; import static de.cotto.lndmanagej.model.NodeFixtures.ALIAS; +import static de.cotto.lndmanagej.model.NodeWarningsFixtures.NODE_WARNINGS; import static de.cotto.lndmanagej.model.OnChainCostsFixtures.ON_CHAIN_COSTS; import static de.cotto.lndmanagej.model.OnlineReportFixtures.ONLINE_REPORT; import static de.cotto.lndmanagej.model.OnlineReportFixtures.ONLINE_REPORT_OFFLINE; @@ -27,7 +28,8 @@ public class NodeDetailsFixtures { BALANCE_INFORMATION_2, ONLINE_REPORT, FEE_REPORT, - REBALANCE_REPORT + REBALANCE_REPORT, + NODE_WARNINGS ); public static final NodeDetails NODE_DETAILS_EMPTY = new NodeDetails( PUBKEY, @@ -40,6 +42,7 @@ public class NodeDetailsFixtures { BalanceInformation.EMPTY, ONLINE_REPORT_OFFLINE, FeeReport.EMPTY, - RebalanceReport.EMPTY + RebalanceReport.EMPTY, + NodeWarnings.NONE ); } diff --git a/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningFixtures.java b/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningFixtures.java new file mode 100644 index 00000000..48486e1c --- /dev/null +++ b/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningFixtures.java @@ -0,0 +1,6 @@ +package de.cotto.lndmanagej.model; + +public class NodeWarningFixtures { + public static final NodeOnlinePercentageWarning NODE_ONLINE_PERCENTAGE_WARNING = + new NodeOnlinePercentageWarning(51); +} diff --git a/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningsFixtures.java b/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningsFixtures.java new file mode 100644 index 00000000..a7c87d4d --- /dev/null +++ b/model/src/testFixtures/java/de/cotto/lndmanagej/model/NodeWarningsFixtures.java @@ -0,0 +1,9 @@ +package de.cotto.lndmanagej.model; + +import static de.cotto.lndmanagej.model.NodeWarningFixtures.NODE_ONLINE_PERCENTAGE_WARNING; + +public class NodeWarningsFixtures { + public static final NodeWarnings NODE_WARNINGS = new NodeWarnings( + NODE_ONLINE_PERCENTAGE_WARNING + ); +} diff --git a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java index 9cbba977..53bea253 100644 --- a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/NodeControllerIT.java @@ -97,6 +97,7 @@ class NodeControllerIT { .andExpect(jsonPath("$.balance.remoteAvailable", is("203"))) .andExpect(jsonPath("$.feeReport.earned", is("1234"))) .andExpect(jsonPath("$.feeReport.sourced", is("567"))) + .andExpect(jsonPath("$.nodeWarnings[0].onlinePercentage", is(51))) .andExpect(jsonPath("$.onChainCosts.openCosts", is("1000"))) .andExpect(jsonPath("$.onChainCosts.closeCosts", is("2000"))) .andExpect(jsonPath("$.onChainCosts.sweepCosts", is("3000"))) diff --git a/web/src/integrationTest/java/de/cotto/lndmanagej/controller/WarningsControllerIT.java b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/WarningsControllerIT.java new file mode 100644 index 00000000..20206f20 --- /dev/null +++ b/web/src/integrationTest/java/de/cotto/lndmanagej/controller/WarningsControllerIT.java @@ -0,0 +1,47 @@ +package de.cotto.lndmanagej.controller; + +import de.cotto.lndmanagej.model.ChannelIdResolver; +import de.cotto.lndmanagej.model.NodeWarnings; +import de.cotto.lndmanagej.service.NodeWarningsService; +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 de.cotto.lndmanagej.model.NodeWarningsFixtures.NODE_WARNINGS; +import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; +import static org.hamcrest.Matchers.hasSize; +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; + +@WebMvcTest(controllers = WarningsController.class) +class WarningsControllerIT { + private static final String NODE_PREFIX = "/api/node/" + PUBKEY; + + @Autowired + private MockMvc mockMvc; + + @MockBean + @SuppressWarnings("unused") + private ChannelIdResolver channelIdResolver; + + @MockBean + private NodeWarningsService nodeWarningsService; + + @Test + void getWarningsForNode() throws Exception { + when(nodeWarningsService.getNodeWarnings(PUBKEY)).thenReturn(NODE_WARNINGS); + mockMvc.perform(get(NODE_PREFIX + "/warnings")) + .andExpect(jsonPath("$.nodeWarnings[0].onlinePercentage", is(51))); + } + + @Test + void getWarningsForNode_empty() throws Exception { + when(nodeWarningsService.getNodeWarnings(PUBKEY)).thenReturn(NodeWarnings.NONE); + mockMvc.perform(get(NODE_PREFIX + "/warnings")) + .andExpect(jsonPath("$.nodeWarnings", hasSize(0))); + } +} \ No newline at end of file diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/WarningsController.java b/web/src/main/java/de/cotto/lndmanagej/controller/WarningsController.java new file mode 100644 index 00000000..07a6e7ce --- /dev/null +++ b/web/src/main/java/de/cotto/lndmanagej/controller/WarningsController.java @@ -0,0 +1,30 @@ +package de.cotto.lndmanagej.controller; + +import com.codahale.metrics.annotation.Timed; +import de.cotto.lndmanagej.controller.dto.NodeWarningsDto; +import de.cotto.lndmanagej.controller.dto.ObjectMapperConfiguration; +import de.cotto.lndmanagej.model.Pubkey; +import de.cotto.lndmanagej.service.NodeWarningsService; +import org.springframework.context.annotation.Import; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/") +@Import(ObjectMapperConfiguration.class) +public class WarningsController { + private final NodeWarningsService nodeWarningsService; + + public WarningsController(NodeWarningsService nodeWarningsService) { + this.nodeWarningsService = nodeWarningsService; + } + + @Timed + @GetMapping("/node/{pubkey}/warnings") + public NodeWarningsDto getWarningsForNode(@PathVariable Pubkey pubkey) { + return NodeWarningsDto.createFromModel(nodeWarningsService.getNodeWarnings(pubkey)); + } + +} diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDto.java b/web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDto.java index c3d1a951..496e3faf 100644 --- a/web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDto.java +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDto.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import de.cotto.lndmanagej.model.ChannelId; import de.cotto.lndmanagej.model.NodeDetails; +import de.cotto.lndmanagej.model.NodeWarning; import de.cotto.lndmanagej.model.Pubkey; import java.util.List; @@ -19,7 +20,8 @@ public record NodeDetailsDto( BalanceInformationDto balance, OnlineReportDto onlineReport, FeeReportDto feeReport, - RebalanceReportDto rebalanceReport + RebalanceReportDto rebalanceReport, + List nodeWarnings ) { public static NodeDetailsDto createFromModel(NodeDetails nodeDetails) { return new NodeDetailsDto( @@ -33,7 +35,8 @@ public record NodeDetailsDto( BalanceInformationDto.createFromModel(nodeDetails.balanceInformation()), OnlineReportDto.createFromModel(nodeDetails.onlineReport()), FeeReportDto.createFromModel(nodeDetails.feeReport()), - RebalanceReportDto.createFromModel(nodeDetails.rebalanceReport()) + RebalanceReportDto.createFromModel(nodeDetails.rebalanceReport()), + nodeDetails.nodeWarnings().warnings() ); } } diff --git a/web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDto.java b/web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDto.java new file mode 100644 index 00000000..b0bee1a4 --- /dev/null +++ b/web/src/main/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDto.java @@ -0,0 +1,12 @@ +package de.cotto.lndmanagej.controller.dto; + +import de.cotto.lndmanagej.model.NodeWarning; +import de.cotto.lndmanagej.model.NodeWarnings; + +import java.util.List; + +public record NodeWarningsDto(List nodeWarnings) { + public static NodeWarningsDto createFromModel(NodeWarnings nodeWarnings) { + return new NodeWarningsDto(nodeWarnings.warnings()); + } +} diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/WarningsControllerTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/WarningsControllerTest.java new file mode 100644 index 00000000..eee1041b --- /dev/null +++ b/web/src/test/java/de/cotto/lndmanagej/controller/WarningsControllerTest.java @@ -0,0 +1,30 @@ +package de.cotto.lndmanagej.controller; + +import de.cotto.lndmanagej.controller.dto.NodeWarningsDto; +import de.cotto.lndmanagej.service.NodeWarningsService; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static de.cotto.lndmanagej.model.NodeWarningsFixtures.NODE_WARNINGS; +import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class WarningsControllerTest { + @InjectMocks + private WarningsController warningsController; + + @Mock + private NodeWarningsService nodeWarningsService; + + @Test + void getWarningsForNode() { + when(nodeWarningsService.getNodeWarnings(PUBKEY)).thenReturn(NODE_WARNINGS); + assertThat(warningsController.getWarningsForNode(PUBKEY)) + .isEqualTo(NodeWarningsDto.createFromModel(NODE_WARNINGS)); + } +} \ No newline at end of file diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDtoTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDtoTest.java index 9e659789..d876db5c 100644 --- a/web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDtoTest.java +++ b/web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeDetailsDtoTest.java @@ -12,6 +12,7 @@ import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_4; import static de.cotto.lndmanagej.model.FeeReportFixtures.FEE_REPORT; import static de.cotto.lndmanagej.model.NodeDetailsFixtures.NODE_DETAILS; import static de.cotto.lndmanagej.model.NodeFixtures.ALIAS; +import static de.cotto.lndmanagej.model.NodeWarningsFixtures.NODE_WARNINGS; import static de.cotto.lndmanagej.model.OnChainCostsFixtures.ON_CHAIN_COSTS; import static de.cotto.lndmanagej.model.OnlineReportFixtures.ONLINE_REPORT; import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY; @@ -32,7 +33,8 @@ class NodeDetailsDtoTest { BalanceInformationDto.createFromModel(BALANCE_INFORMATION_2), OnlineReportDto.createFromModel(ONLINE_REPORT), FeeReportDto.createFromModel(FEE_REPORT), - RebalanceReportDto.createFromModel(REBALANCE_REPORT) + RebalanceReportDto.createFromModel(REBALANCE_REPORT), + NODE_WARNINGS.warnings() ); assertThat(NodeDetailsDto.createFromModel(NODE_DETAILS)).isEqualTo(expected); } diff --git a/web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDtoTest.java b/web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDtoTest.java new file mode 100644 index 00000000..6447adcd --- /dev/null +++ b/web/src/test/java/de/cotto/lndmanagej/controller/dto/NodeWarningsDtoTest.java @@ -0,0 +1,14 @@ +package de.cotto.lndmanagej.controller.dto; + +import org.junit.jupiter.api.Test; + +import static de.cotto.lndmanagej.model.NodeWarningsFixtures.NODE_WARNINGS; +import static org.assertj.core.api.Assertions.assertThat; + +class NodeWarningsDtoTest { + @Test + void createFromModel() { + assertThat(NodeWarningsDto.createFromModel(NODE_WARNINGS)) + .isEqualTo(new NodeWarningsDto(NODE_WARNINGS.warnings())); + } +} \ No newline at end of file