Skip to content

feat: first versions for a framework to get metrics from the backend #113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.exception;

public class MetricNotFoundException extends RuntimeException {
public MetricNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.resource;

import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.cardanofoundation.lob.app.accounting_reporting_core.resource.views.MetricDataResponse;
import org.cardanofoundation.lob.app.accounting_reporting_core.resource.views.MetricView;
import org.cardanofoundation.lob.app.accounting_reporting_core.service.internal.metrics.MetricService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/metrics")
@CrossOrigin(origins = "http://localhost:3000")
@RequiredArgsConstructor
@Slf4j
public class MetricController {

private final MetricService metricService;

@Tag(name = "Dashboard", description = "Available Dashboards")
@GetMapping(value = "/availableMetrics", produces = "application/json")
public ResponseEntity<MetricView> availableDashboards() {
return ResponseEntity.ok(new MetricView(metricService.getAvailableMetrics()));
}

@Tag(name = "Dashboard", description = "Get Data for Dashboard")
@PostMapping(value = "/data", produces = "application/json")
public ResponseEntity<MetricDataResponse> getDashboardData(@RequestBody MetricView metricView) {
return ResponseEntity.ok(new MetricDataResponse(metricService.getData(metricView.getMetrics(), metricView.getStartDate(), metricView.getEndDate())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.resource.views;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;
import java.util.Map;

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class MetricDataResponse {

Map<String, List<Object>> data;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.resource.views;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class MetricView {

Map<String, List<String>> metrics;
Date startDate;
Date endDate;

public MetricView(Map<String, List<String>> metrics) {
this.metrics = metrics;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.service.internal.metrics;

import lombok.Getter;
import org.cardanofoundation.lob.app.accounting_reporting_core.exception.MetricNotFoundException;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public abstract class MetricExecutor {

protected Map<String, MetricFunction> metrics;

@Getter
protected String name;

public List<String> getAvailableMetrics() {
return Optional.ofNullable(metrics)
.orElseThrow(() -> new MetricNotFoundException(String.format("Metrics %s not initialized", name)))
.keySet().stream().toList();
}

public Object getData(String id, Date startDate, Date endDate) {
Map<String, MetricFunction> metricsNotInitialized = Optional.ofNullable(metrics).orElseThrow(() -> new MetricNotFoundException("Metrics not initialized"));
MetricFunction metricFunction = metricsNotInitialized.getOrDefault(id, (Date start, Date end) -> {
throw new MetricNotFoundException(String.format("Metric Function %s not found in %s", id, name));
});
return metricFunction.getData(startDate, endDate);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.service.internal.metrics;

import java.util.Date;

@FunctionalInterface
public interface MetricFunction {

Object getData(Date startDate, Date endDate);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.service.internal.metrics;

import java.util.Date;
import java.util.List;
import java.util.Map;

public interface MetricService {

Map<String, List<String>> getAvailableMetrics();
Map<String, List<Object>> getData(Map<String, List<String>> metrics, Date startDate, Date endDate);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.service.internal.metrics;

import lombok.RequiredArgsConstructor;
import org.cardanofoundation.lob.app.accounting_reporting_core.exception.MetricNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class MetricServiceImpl implements MetricService{

private final List<MetricExecutor> metricExecutors;

public Map<String, List<String>> getAvailableMetrics() {
return metricExecutors.stream()
.map(metricExecutorInterface -> Map.entry(metricExecutorInterface.getName(),
metricExecutorInterface.getAvailableMetrics()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

@Override
public Map<String, List<Object>> getData(Map<String, List<String>> metrics, Date startDate, Date endDate) {
return metrics.entrySet().stream()
.map(metric -> {
MetricExecutor metricExecutor = getMetricExecutor(metric.getKey());
List<Object> metricData = metric.getValue().stream().map(s -> metricExecutor.getData(s, startDate, endDate)).toList();

return Map.entry(metric.getKey(), metricData);
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

private MetricExecutor getMetricExecutor(String metricName) {
return metricExecutors.stream()
.filter(metricExecutorInterface -> metricExecutorInterface.getName().equals(metricName))
.findFirst()
.orElseThrow(() -> new MetricNotFoundException(String.format("Metric %s not found", metricName)));
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.cardanofoundation.lob.app.accounting_reporting_core.service.internal.metrics.executors;

import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.cardanofoundation.lob.app.accounting_reporting_core.service.internal.metrics.MetricExecutor;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class BalanceSheetMetricService extends MetricExecutor {

@PostConstruct
public void init() {
name = "BalanceSheet";
metrics = Map.of(
"assets", this::getAssets
);
}

private Map<String, Integer> getAssets(Date startDate, Date endDate) {
return Map.of(
"totalAssets", 1000
);
}
}
Loading