3-ftransform-forecasting #5
@ -34,10 +34,12 @@ dependencies {
|
|||||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
|
||||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
|
||||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
|
||||||
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux'
|
||||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J
|
implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J
|
||||||
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '3.0.0'
|
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '3.0.0'
|
||||||
implementation group: 'org.javassist', name: 'javassist', version: '3.25.0-GA'
|
implementation group: 'org.javassist', name: 'javassist', version: '3.25.0-GA'
|
||||||
implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: versionJetty
|
implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: versionJetty
|
||||||
|
implementation group: 'org.json', name: 'json', version: '20220320'
|
||||||
|
|
||||||
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind'
|
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind'
|
||||||
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations'
|
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations'
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package ru.ulstu.configuration;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.*;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class WebClientConfiguration {
|
||||||
|
@Bean
|
||||||
|
public WebClient webClient(WebClient.Builder webClientBuilder) {
|
||||||
|
return webClientBuilder.build(); //contentType(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
|
}
|
||||||
|
}
|
40
src/main/java/ru/ulstu/controller/AnomalyController.java
Normal file
40
src/main/java/ru/ulstu/controller/AnomalyController.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package ru.ulstu.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import ru.ulstu.configuration.ApiConfiguration;
|
||||||
|
import ru.ulstu.datamodel.exception.ModelingException;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.db.DbService;
|
||||||
|
import ru.ulstu.db.model.TimeSeriesSet;
|
||||||
|
import ru.ulstu.estimate.CompressionMetricService;
|
||||||
|
import ru.ulstu.service.UtilService;
|
||||||
|
import ru.ulstu.target.AnomalyDifferenceSmoothed;
|
||||||
|
import ru.ulstu.target.Target;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(ApiConfiguration.API_1_0)
|
||||||
|
public class AnomalyController {
|
||||||
|
|
||||||
|
private final DbService dbService;
|
||||||
|
private final Target target;
|
||||||
|
|
||||||
|
public AnomalyController(CompressionMetricService compressionMetricService, DbService dbService, AnomalyDifferenceSmoothed anomalyDifferenceSmoothed) {
|
||||||
|
this.dbService = dbService;
|
||||||
|
this.target = anomalyDifferenceSmoothed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping ("getAnomalyAtDifferenceSmothed")
|
||||||
|
@Operation(description = "Получить аномальные значения")
|
||||||
|
public TimeSeries getAnomalyAtDifferenceSmothed(@RequestParam("setKey") String setKey, @RequestParam("timeSeriesKey") String timeSeriesKey) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException {
|
||||||
|
var timeSeries = dbService.getTimeSeries(new TimeSeriesSet(setKey), timeSeriesKey);
|
||||||
|
var timeSeriesResult = target.calculate(timeSeries);
|
||||||
|
return timeSeriesResult;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package ru.ulstu.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import ru.ulstu.configuration.ApiConfiguration;
|
||||||
|
import ru.ulstu.datamodel.exception.ModelingException;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.db.DbService;
|
||||||
|
import ru.ulstu.db.model.TimeSeriesSet;
|
||||||
|
import ru.ulstu.estimate.CompressionMetricService;
|
||||||
|
import ru.ulstu.service.PrometheusService;
|
||||||
|
import ru.ulstu.service.UtilService;
|
||||||
|
import ru.ulstu.target.AnomalyDifferenceSmoothed;
|
||||||
|
import ru.ulstu.target.Target;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(ApiConfiguration.API_1_0)
|
||||||
|
public class CompressionMetricController {
|
||||||
|
|
||||||
|
private final UtilService utilService;
|
||||||
|
private final DbService dbService;
|
||||||
|
private final PrometheusService prometheusService;
|
||||||
|
private final CompressionMetricService compressionMetricService;
|
||||||
|
private final Target target;
|
||||||
|
|
||||||
|
public CompressionMetricController(UtilService utilService, DbService dbService, PrometheusService prometheusService, CompressionMetricService compressionMetricService, AnomalyDifferenceSmoothed anomalyDifferenceSmoothed) {
|
||||||
|
this.utilService = utilService;
|
||||||
|
this.dbService = dbService;
|
||||||
|
this.prometheusService = prometheusService;
|
||||||
|
this.compressionMetricService = compressionMetricService;
|
||||||
|
this.target = anomalyDifferenceSmoothed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("getMetricAtAnomaly")
|
||||||
|
@Operation(description = "Получить метрику сжатия")
|
||||||
|
public ResponseEntity<TimeSeries> getMetricAtAnomaly(@RequestParam("setKey") String setKey, @RequestParam("timeSeriesKey") String timeSeriesKey) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException {
|
||||||
|
var timeSeries = dbService.getTimeSeries(new TimeSeriesSet(setKey), timeSeriesKey);
|
||||||
|
var timeSeriesResult = compressionMetricService.getCompressionTimeSeries(timeSeries);
|
||||||
|
return new ResponseEntity<>(timeSeriesResult, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("getMetricAtAnomalyOfRandom")
|
||||||
|
@Operation(description = "Получить метрику сжатия")
|
||||||
|
public ResponseEntity<TimeSeries> getMetricAtAnomalyOfRandom(@RequestParam("lenght") int len) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||||
|
var timeSeries = utilService.getRandomTimeSeries(len);
|
||||||
|
var timeSeriesResult = compressionMetricService.getCompressionTimeSeries(timeSeries);
|
||||||
|
return new ResponseEntity<>(timeSeriesResult, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("getMetricAtAnomalyOfPrometheus")
|
||||||
|
@Operation(description = "Получить метрику сжатия")
|
||||||
|
public ResponseEntity<TimeSeries> getMetricAtAnomalyOfPrometheus(@RequestParam("query") String query) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||||
|
var timeSeries = prometheusService.executionQueryRange(query);
|
||||||
|
var timeSeriesResult = compressionMetricService.getCompressionTimeSeries(timeSeries);
|
||||||
|
return new ResponseEntity<>(timeSeriesResult, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TimeSeries {
|
public class TimeSeries {
|
||||||
@ -88,6 +89,20 @@ public class TimeSeries {
|
|||||||
throw new RuntimeException("Индекс выходит за границы временного ряда");
|
throw new RuntimeException("Индекс выходит за границы временного ряда");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TimeSeriesValue getMax() {
|
||||||
|
if ((values.size() > 0)) {
|
||||||
|
return values.stream().max(Comparator.comparing(TimeSeriesValue::getValue)).get();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Временной ряд пустой");
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeriesValue getMin() {
|
||||||
|
if ((values.size() > 0)) {
|
||||||
|
return values.stream().min(Comparator.comparing(TimeSeriesValue::getValue)).get();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Временной ряд пустой");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TimeSeries{" +
|
return "TimeSeries{" +
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
package ru.ulstu.estimate;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.datamodel.Model;
|
||||||
|
import ru.ulstu.datamodel.ModelingResult;
|
||||||
|
import ru.ulstu.datamodel.exception.ModelingException;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
||||||
|
import ru.ulstu.method.MethodParamValue;
|
||||||
|
import ru.ulstu.method.ftransform.FTransform;
|
||||||
|
import ru.ulstu.score.ScoreMethod;
|
||||||
|
import ru.ulstu.service.MethodParamBruteForce;
|
||||||
|
import ru.ulstu.service.TimeSeriesService;
|
||||||
|
import ru.ulstu.service.UtilService;
|
||||||
|
import ru.ulstu.target.AnomalyDifferenceSmoothed;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CompressionMetricService {
|
||||||
|
|
||||||
|
private final int DEFAULT_THREAD_COUNT = 10;
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
private final FTransform fTransform;
|
||||||
|
private final MethodParamBruteForce methodParamBruteForce;
|
||||||
|
private final UtilService utilService;
|
||||||
|
private final ScoreMethod scoreMethod;
|
||||||
|
|
||||||
|
private final AnomalyDifferenceSmoothed anomalyDifferenceSmoothed;
|
||||||
|
private final ExecutorService executors = Executors.newFixedThreadPool(DEFAULT_THREAD_COUNT);
|
||||||
|
|
||||||
|
public CompressionMetricService(TimeSeriesService timeSeriesService, FTransform fTransform, MethodParamBruteForce methodParamBruteForce, UtilService utilService, ScoreMethod scoreMethod, AnomalyDifferenceSmoothed anomalyDifferenceSmoothed) {
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
this.fTransform = fTransform;
|
||||||
|
this.methodParamBruteForce = methodParamBruteForce;
|
||||||
|
this.utilService = utilService;
|
||||||
|
this.scoreMethod = scoreMethod;
|
||||||
|
this.anomalyDifferenceSmoothed = anomalyDifferenceSmoothed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeries getCompressionTimeSeries(TimeSeries ts) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||||
|
//ModelingResult modelingResult = timeSeriesService.smoothTimeSeries(ts, "FTransform");
|
||||||
|
ModelingResult modelingResult = getCompressionTimeSeriesWithFTransform(ts);
|
||||||
|
//var ts1 = fTransform.getForecast(ts, )
|
||||||
|
var timeSeriesAnomalyResult = anomalyDifferenceSmoothed.calculate(modelingResult.getTimeSeries());
|
||||||
|
var timeSeriesAnomaly = anomalyDifferenceSmoothed.calculate(ts);
|
||||||
|
System.out.println(ts.getLength()+"\t"
|
||||||
|
+timeSeriesAnomaly.getLength()+"\t"
|
||||||
|
+Math.abs(timeSeriesAnomaly.getLength() - timeSeriesAnomalyResult.getLength())+"\t"
|
||||||
|
+(double)modelingResult.getTimeSeries().getLength()/ts.getLength()+"\t"
|
||||||
|
+modelingResult.getScore().getDoubleValue());
|
||||||
|
System.out.println(timeSeriesAnomaly);
|
||||||
|
System.out.println(timeSeriesAnomalyResult);
|
||||||
|
System.out.println(utilService.getTimeSeriesToString(ts));
|
||||||
|
System.out.println(utilService.getTimeSeriesToString(modelingResult.getTimeSeries()));
|
||||||
|
return modelingResult.getTimeSeries();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ModelingResult getCompressionTimeSeriesWithFTransform(TimeSeries timeSeries) throws ExecutionException, InterruptedException {
|
||||||
|
List<Future<ModelingResult>> results = new ArrayList<>();
|
||||||
|
List<ModelingResult> results2 = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
Map<LocalDateTime, Double> tsValues = timeSeries.getValues().stream()
|
||||||
|
.collect(Collectors.toMap(TimeSeriesValue::getDate, TimeSeriesValue::getValue,
|
||||||
|
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
|
||||||
|
|
||||||
|
|
||||||
|
List<List<MethodParamValue>> availableParametersValues = methodParamBruteForce.getAvailableParametersValues(timeSeries, fTransform.getAvailableParameters());
|
||||||
|
for (List<MethodParamValue> parametersValues : availableParametersValues) {
|
||||||
|
results.add(executors.submit(() -> {
|
||||||
|
Model model = fTransform.getModel(timeSeries, parametersValues);
|
||||||
|
return new ModelingResult(model.getTimeSeriesModel(),
|
||||||
|
null,
|
||||||
|
parametersValues,
|
||||||
|
scoreMethod.getScore(tsValues, model.getTimeSeriesModel()), fTransform);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (Future<ModelingResult> futureModelingResult : results) {
|
||||||
|
results2.add(futureModelingResult.get());
|
||||||
|
}
|
||||||
|
return results2.stream()
|
||||||
|
.min(Comparator.comparing(modelingResult -> modelingResult.getScore().getDoubleValue()))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
src/main/java/ru/ulstu/http/HttpClientService.java
Normal file
11
src/main/java/ru/ulstu/http/HttpClientService.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package ru.ulstu.http;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class HttpClientService {
|
||||||
|
|
||||||
|
public void get(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
66
src/main/java/ru/ulstu/http/WebClientService.java
Normal file
66
src/main/java/ru/ulstu/http/WebClientService.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package ru.ulstu.http;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.reactive.function.BodyInserters;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WebClientService {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(WebClientService.class);
|
||||||
|
private final WebClient client;
|
||||||
|
|
||||||
|
public WebClientService(WebClient client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject post(String url, JSONObject postData) {
|
||||||
|
log.debug("Service call: {}", url);
|
||||||
|
JSONObject response = null;
|
||||||
|
try {
|
||||||
|
response = new JSONObject(Optional.ofNullable(client
|
||||||
|
.post()
|
||||||
|
.uri(url)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.body(BodyInserters.fromValue(postData.toString()))
|
||||||
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.toFuture().get()).orElse("{response:\"empty\"}"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new JSONObject("{response:\"empty\"}");
|
||||||
|
}
|
||||||
|
log.debug("Service response: {}", response);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONArray get(String url) {
|
||||||
|
log.debug("Service call: {}", url);
|
||||||
|
try {
|
||||||
|
String response = client
|
||||||
|
.get()
|
||||||
|
.uri(url)
|
||||||
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.timeout(Duration.ofMinutes(1))
|
||||||
|
.toFuture().get();
|
||||||
|
if (response.startsWith("[")) {
|
||||||
|
return new JSONArray(response);
|
||||||
|
} else {
|
||||||
|
JSONArray jsonArray = new JSONArray();
|
||||||
|
jsonArray.put(0, new JSONObject(response));
|
||||||
|
return jsonArray;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,21 @@
|
|||||||
package ru.ulstu.method.ftransform;
|
package ru.ulstu.method.ftransform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Треугольная функция принадлежности
|
* Базисная функция
|
||||||
*/
|
*/
|
||||||
public class AComponent {
|
public class AComponent {
|
||||||
private int start; // левая граница треугольника
|
private double start; // левая граница треугольника
|
||||||
private int end; // правая граница треугольника
|
private double end; // правая граница треугольника
|
||||||
private int top; // вершина треугольника
|
private double top; // вершина треугольника
|
||||||
|
|
||||||
public int getStart() {
|
public double getStart() {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AComponent() {
|
public AComponent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AComponent(int start, int top, int end) {
|
public AComponent(double start, double top, double end) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.top = top;
|
this.top = top;
|
||||||
this.end = end;
|
this.end = end;
|
||||||
@ -26,19 +26,23 @@ public class AComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getEnd() {
|
public double getEnd() {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnd(int end) {
|
public void setEnd(double end) {
|
||||||
this.end = end;
|
this.end = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTop() {
|
public double getTop() {
|
||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTop(int top) {
|
public int getTopInt() {
|
||||||
|
return (int) Math.round(top);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTop(double top) {
|
||||||
this.top = top;
|
this.top = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,4 +58,9 @@ public class AComponent {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "start=" + start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,19 @@ package ru.ulstu.method.ftransform;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import ru.ulstu.datamodel.Model;
|
import ru.ulstu.datamodel.Model;
|
||||||
import ru.ulstu.datamodel.ts.TimeSeries;
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
||||||
import ru.ulstu.method.Method;
|
import ru.ulstu.method.Method;
|
||||||
import ru.ulstu.method.MethodParamValue;
|
import ru.ulstu.method.MethodParamValue;
|
||||||
import ru.ulstu.method.MethodParameter;
|
import ru.ulstu.method.MethodParameter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class FTransform extends Method {
|
public class FTransform extends Method {
|
||||||
|
private final static int NUMBER_OF_FUZZY_VALUES = 3;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FTransformModel getModelOfValidTimeSeries(TimeSeries ts,
|
protected FTransformModel getModelOfValidTimeSeries(TimeSeries ts,
|
||||||
@ -29,8 +34,8 @@ public class FTransform extends Method {
|
|||||||
sum1 += membership * ts.getNumericValue(j);
|
sum1 += membership * ts.getNumericValue(j);
|
||||||
sum2 += membership;
|
sum2 += membership;
|
||||||
}
|
}
|
||||||
piecewiseLinearTrend.addValue(ts.getValue(aComponent.getTop()), sum1 / sum2);
|
piecewiseLinearTrend.addValue(ts.getValue(aComponent.getTopInt()), sum1 / sum2);
|
||||||
tsModel.addValue(ts.getValue(aComponent.getTop()), sum1 / sum2);
|
tsModel.addValue(ts.getValue(aComponent.getTopInt()), sum1 / sum2);
|
||||||
}
|
}
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
@ -41,27 +46,27 @@ public class FTransform extends Method {
|
|||||||
while (currentPoint < ts.getLength()) {
|
while (currentPoint < ts.getLength()) {
|
||||||
int startPoint = (currentPoint == 0)
|
int startPoint = (currentPoint == 0)
|
||||||
? 0
|
? 0
|
||||||
: piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop();
|
: piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTopInt();
|
||||||
AComponent bf = new AComponent(startPoint, currentPoint, (int) (currentPoint + Math.round(numberOfCoveredPoints / 2.0)));
|
AComponent aComponent = new AComponent(startPoint, currentPoint, (int) (currentPoint + Math.round(numberOfCoveredPoints / 2.0)));
|
||||||
if (bf.getStart() < 0) {
|
if (aComponent.getStart() < 0) {
|
||||||
bf.setStart(0);
|
aComponent.setStart(0);
|
||||||
}
|
}
|
||||||
if (bf.getEnd() > ts.getLength() - 1) {
|
if (aComponent.getEnd() > ts.getLength() - 1) {
|
||||||
bf.setEnd(ts.getLength() - 1);
|
aComponent.setEnd(ts.getLength() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bf.getTop() > ts.getLength() - 1) {
|
if (aComponent.getTop() > ts.getLength() - 1) {
|
||||||
bf.setTop(ts.getLength() - 1);
|
aComponent.setTop(ts.getLength() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
piecewiseLinearTrend.add(bf);
|
piecewiseLinearTrend.add(aComponent);
|
||||||
currentPoint += deltaForTriangle;
|
currentPoint += deltaForTriangle;
|
||||||
}
|
}
|
||||||
if (piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd() != piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop()) {
|
if (piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd() != piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop()) {
|
||||||
AComponent bf = new AComponent(piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop(),
|
AComponent aComponent = new AComponent(piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop(),
|
||||||
piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd(),
|
piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd(),
|
||||||
piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd());
|
piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd());
|
||||||
piecewiseLinearTrend.add(bf);
|
piecewiseLinearTrend.add(aComponent);
|
||||||
}
|
}
|
||||||
return piecewiseLinearTrend;
|
return piecewiseLinearTrend;
|
||||||
}
|
}
|
||||||
@ -69,6 +74,25 @@ public class FTransform extends Method {
|
|||||||
@Override
|
@Override
|
||||||
protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) {
|
protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) {
|
||||||
FTransformModel fTransformModel = (FTransformModel) model;
|
FTransformModel fTransformModel = (FTransformModel) model;
|
||||||
|
double minValue = fTransformModel.getPiecewiseLinearTrend().getValues().stream().map(TimeSeriesValue::getValue).min(Double::compareTo).orElse(0.0);
|
||||||
|
double maxValue = fTransformModel.getPiecewiseLinearTrend().getValues().stream().map(TimeSeriesValue::getValue).max(Double::compareTo).orElse(0.0);
|
||||||
|
List<AComponent> fuzzyValues = new ArrayList<>();
|
||||||
|
double diff = (maxValue - minValue) / NUMBER_OF_FUZZY_VALUES;
|
||||||
|
for (int i = 0; i < NUMBER_OF_FUZZY_VALUES; i++) {
|
||||||
|
fuzzyValues.add(new AComponent(minValue + i * diff, minValue + i * diff + diff / 2, minValue + i * diff + diff));
|
||||||
|
}
|
||||||
|
List<AComponent> fuzzyTimeSeries = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < model.getTimeSeriesModel().getLength(); i++) {
|
||||||
|
for (AComponent fuzzyValue : fuzzyValues) {
|
||||||
|
if (model.getTimeSeriesModel().getValue(i).getValue() >= fuzzyValue.getStart()
|
||||||
|
&& model.getTimeSeriesModel().getValue(i).getValue() <= fuzzyValue.getEnd()) {
|
||||||
|
fuzzyTimeSeries.add(fuzzyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int t = 1; t < forecast.getLength(); t++) {
|
for (int t = 1; t < forecast.getLength(); t++) {
|
||||||
forecast.getValues().get(t).setValue(fTransformModel.getPiecewiseLinearTrend().getLastValue().getValue());
|
forecast.getValues().get(t).setValue(fTransformModel.getPiecewiseLinearTrend().getLastValue().getValue());
|
||||||
}
|
}
|
||||||
@ -80,6 +104,16 @@ public class FTransform extends Method {
|
|||||||
return FTransformModel.getAvailableParameters();
|
return FTransformModel.getAvailableParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private AComponent findFuzzyValueByPrevious(List<AComponent> fuzzyTimeSeries, AComponent currentFuzzyValue) {
|
||||||
|
// Map<AComponent, Integer> mostFrequentValues = new HashMap<>();
|
||||||
|
// for (int i = 0; i < fuzzyTimeSeries.size() - 1; i++) {
|
||||||
|
// if (fuzzyTimeSeries.get(i).equals(currentFuzzyValue)) {
|
||||||
|
// mostFrequentValues.put(fuzzyTimeSeries.get(i + 1), mostFrequentValues.getOrDefault(fuzzyTimeSeries.get(i + 1), 0) + 1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// mostFrequentValues.entrySet().stream()
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "F - преобразование";
|
return "F - преобразование";
|
||||||
|
32
src/main/java/ru/ulstu/score/AnomalyCompressionScore.java
Normal file
32
src/main/java/ru/ulstu/score/AnomalyCompressionScore.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package ru.ulstu.score;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.ulstu.datamodel.exception.ModelingException;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
||||||
|
import ru.ulstu.target.AnomalyDifferenceSmoothed;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import static java.lang.Math.abs;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AnomalyCompressionScore extends ScoreMethod {
|
||||||
|
|
||||||
|
private final AnomalyDifferenceSmoothed anomalyDifferenceSmoothed;
|
||||||
|
public AnomalyCompressionScore(AnomalyDifferenceSmoothed anomalyDifferenceSmoothed) {
|
||||||
|
super("Smape, %");
|
||||||
|
this.anomalyDifferenceSmoothed = anomalyDifferenceSmoothed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Number evaluate(Map<LocalDateTime, Double> tsValues, TimeSeries model) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||||
|
var timeSeriesAnomalyResult = anomalyDifferenceSmoothed.calculate(model);
|
||||||
|
var timeSeriesAnomaly = anomalyDifferenceSmoothed.calculate(tsValues);
|
||||||
|
// туду: добавить сравнение аномальных точек
|
||||||
|
return (double)model.getLength()/tsValues.size() + Math.abs(timeSeriesAnomaly.getLength() - timeSeriesAnomalyResult.getLength());
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,11 @@ import ru.ulstu.datamodel.exception.ModelingException;
|
|||||||
import ru.ulstu.datamodel.ts.TimeSeries;
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public abstract class ScoreMethod {
|
public abstract class ScoreMethod {
|
||||||
private final String name;
|
private final String name;
|
||||||
@ -16,11 +18,11 @@ public abstract class ScoreMethod {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Score getScore(Map<LocalDateTime, Double> tsValues, TimeSeries model) throws ModelingException {
|
public Score getScore(Map<LocalDateTime, Double> tsValues, TimeSeries model) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||||
return new Score(this, evaluate(tsValues, model));
|
return new Score(this, evaluate(tsValues, model));
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Number evaluate(Map<LocalDateTime, Double> tsValues, TimeSeries model) throws ModelingException;
|
public abstract Number evaluate(Map<LocalDateTime, Double> tsValues, TimeSeries model) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
|
@ -28,7 +28,7 @@ import java.util.concurrent.Future;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class MethodParamBruteForce {
|
public class MethodParamBruteForce {
|
||||||
private final int DEFAULT_THREAD_COUNT = 50;
|
private final int DEFAULT_THREAD_COUNT = 50;
|
||||||
private final List<Method> methods;
|
private final List<Method> methods;
|
||||||
private final ScoreMethod scoreMethod = new Smape();
|
private final ScoreMethod scoreMethod = new Smape();
|
||||||
@ -175,7 +175,7 @@ class MethodParamBruteForce {
|
|||||||
return getSmoothedTimeSeries(timeSeries, methods);
|
return getSmoothedTimeSeries(timeSeries, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<List<MethodParamValue>> getAvailableParametersValues(TimeSeries timeSeries, List<MethodParameter> availableParameters) {
|
public List<List<MethodParamValue>> getAvailableParametersValues(TimeSeries timeSeries, List<MethodParameter> availableParameters) {
|
||||||
List<List<MethodParamValue>> result = new ArrayList<>();
|
List<List<MethodParamValue>> result = new ArrayList<>();
|
||||||
Map<MethodParameter, Integer> parameterOffset = new TreeMap<>();
|
Map<MethodParameter, Integer> parameterOffset = new TreeMap<>();
|
||||||
Map<MethodParameter, List<Number>> parameterValues = new TreeMap<>();
|
Map<MethodParameter, List<Number>> parameterValues = new TreeMap<>();
|
||||||
|
87
src/main/java/ru/ulstu/service/PrometheusService.java
Normal file
87
src/main/java/ru/ulstu/service/PrometheusService.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package ru.ulstu.service;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
||||||
|
import ru.ulstu.http.WebClientService;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PrometheusService {
|
||||||
|
|
||||||
|
private static final String PROMETHEUS_API_URL = "http://prometheus.athene.tech/api/v1/";
|
||||||
|
private final WebClientService httpService;
|
||||||
|
|
||||||
|
public PrometheusService(WebClientService httpService) {
|
||||||
|
this.httpService = httpService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeries executionQuery(String query){ // example: pve_cpu_usage_ratio{id="lxc/111"}[5h]
|
||||||
|
var timeSeries = new TimeSeries();
|
||||||
|
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(PROMETHEUS_API_URL + "query")
|
||||||
|
.queryParam("query",
|
||||||
|
"pve_cpu_usage_ratio{id='lxc/111'}[1h]");
|
||||||
|
|
||||||
|
var response = httpService.get(PROMETHEUS_API_URL + "query?query=" + query);
|
||||||
|
if (response.getJSONObject(0).getString("status").equals("success")){
|
||||||
|
|
||||||
|
}
|
||||||
|
return timeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeries executionQueryPost(String query){ // example: pve_cpu_usage_ratio{id="lxc/111"}[5h]
|
||||||
|
var timeSeries = new TimeSeries();
|
||||||
|
var postData = new JSONObject();
|
||||||
|
postData.put("query", query);
|
||||||
|
var response = httpService.post(PROMETHEUS_API_URL + "query", postData);
|
||||||
|
// if (response.getJSONObject(0).getString("status").equals("success")){
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
return timeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeries executionQueryRange(String query){
|
||||||
|
int numberTimeSeries = 14;
|
||||||
|
var nowDateTime = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
|
||||||
|
var timeSeries = new TimeSeries();
|
||||||
|
var response = httpService.get(PROMETHEUS_API_URL + "query_range?query=" + query +
|
||||||
|
"&start=" + nowDateTime.minusHours(10).minusMinutes(100).toString()+".004Z" +
|
||||||
|
"&end=" + nowDateTime.minusHours(10).toString()+".004Z" +
|
||||||
|
"&step=15s");
|
||||||
|
var array = response.getJSONObject(0).getJSONObject("data").getJSONArray("result").getJSONObject(numberTimeSeries).getJSONArray("values").toList();
|
||||||
|
for (int i = 0; i < array.size(); i++) {
|
||||||
|
BigDecimal seconds = (BigDecimal)(((ArrayList) array.get(i)).get(0));
|
||||||
|
Double value = Double.parseDouble((String)(((ArrayList) array.get(i)).get(1)));
|
||||||
|
LocalDateTime dateTime =
|
||||||
|
LocalDateTime.ofInstant(Instant.ofEpochSecond(seconds.longValue()), ZoneId.systemDefault());
|
||||||
|
timeSeries.addValue(new TimeSeriesValue(dateTime, value));
|
||||||
|
}
|
||||||
|
return timeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeries executionQueryRangePost(String query){
|
||||||
|
var timeSeries = new TimeSeries();
|
||||||
|
var postData = new JSONObject();
|
||||||
|
postData.put("query", query);
|
||||||
|
postData.put("start", "2023-04-06T00:00:00.004Z");
|
||||||
|
postData.put("end", "2023-04-07T00:00:00.004Z");
|
||||||
|
postData.put("step", "15s");
|
||||||
|
|
||||||
|
var response = httpService.post(PROMETHEUS_API_URL + "query_range", postData);
|
||||||
|
// response.getJSONObject();
|
||||||
|
// if (response.getJSONObject(0).getString("status").equals("success")){
|
||||||
|
// var array = response.getJSONObject(0).getJSONObject("data").getJSONArray("result");
|
||||||
|
// int a = 5;
|
||||||
|
// }
|
||||||
|
return timeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
17
src/main/java/ru/ulstu/target/AnomalyDecompose.java
Normal file
17
src/main/java/ru/ulstu/target/AnomalyDecompose.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package ru.ulstu.target;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AnomalyDecompose extends Target {
|
||||||
|
public AnomalyDecompose() {
|
||||||
|
super("Разложение");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeSeries calculate(TimeSeries model) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
46
src/main/java/ru/ulstu/target/AnomalyDifferenceSmoothed.java
Normal file
46
src/main/java/ru/ulstu/target/AnomalyDifferenceSmoothed.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package ru.ulstu.target;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.datamodel.ModelingResult;
|
||||||
|
import ru.ulstu.datamodel.exception.ModelingException;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
||||||
|
import ru.ulstu.service.TimeSeriesService;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AnomalyDifferenceSmoothed extends Target {
|
||||||
|
|
||||||
|
private final TimeSeriesService timeSeriesService;
|
||||||
|
|
||||||
|
public AnomalyDifferenceSmoothed(TimeSeriesService timeSeriesService) {
|
||||||
|
super("Модель сравнения со сглаженным ВР");
|
||||||
|
this.timeSeriesService = timeSeriesService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeSeries calculate(TimeSeries timeSeries) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||||
|
TimeSeries residual = new TimeSeries();
|
||||||
|
TimeSeries anomalyPoints = new TimeSeries();
|
||||||
|
|
||||||
|
TimeSeries timeSeriesSmooth = timeSeriesService.smoothTimeSeries(timeSeries, "AddTrendAddSeason").getTimeSeries();
|
||||||
|
|
||||||
|
for (int i = 0; i < timeSeries.getLength(); i++) {
|
||||||
|
residual.addValue(new TimeSeriesValue(timeSeries.getValue(i).getDate(),
|
||||||
|
Math.abs(timeSeries.getNumericValue(i) - timeSeriesSmooth.getNumericValue(i))));
|
||||||
|
}
|
||||||
|
|
||||||
|
double diff = timeSeries.getMax().getValue()-timeSeries.getMin().getValue();
|
||||||
|
|
||||||
|
for (int i = 0; i < residual.getLength(); i++) {
|
||||||
|
if (residual.getNumericValue(i)/diff > 0.05) {
|
||||||
|
anomalyPoints.addValue(new TimeSeriesValue(residual.getValue(i).getDate(),
|
||||||
|
timeSeries.getNumericValue(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return anomalyPoints;
|
||||||
|
}
|
||||||
|
}
|
14
src/main/java/ru/ulstu/target/AnomalyPredictive.java
Normal file
14
src/main/java/ru/ulstu/target/AnomalyPredictive.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package ru.ulstu.target;
|
||||||
|
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
|
||||||
|
public class AnomalyPredictive extends Target {
|
||||||
|
public AnomalyPredictive() {
|
||||||
|
super("Прогнозная модель, %");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeSeries calculate(TimeSeries model) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
32
src/main/java/ru/ulstu/target/Target.java
Normal file
32
src/main/java/ru/ulstu/target/Target.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package ru.ulstu.target;
|
||||||
|
|
||||||
|
import ru.ulstu.datamodel.exception.ModelingException;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeries;
|
||||||
|
import ru.ulstu.datamodel.ts.TimeSeriesValue;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
public abstract class Target {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Target(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract TimeSeries calculate(TimeSeries model) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException;
|
||||||
|
|
||||||
|
public TimeSeries calculate(Map<LocalDateTime, Double> values) throws ModelingException, ExecutionException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||||
|
TimeSeries model = new TimeSeries();
|
||||||
|
for (var entry : values.entrySet()) {
|
||||||
|
model.addValue(new TimeSeriesValue(entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
return calculate(model);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ spring.main.banner-mode=off
|
|||||||
logging.level.tech.athene=DEBUG
|
logging.level.tech.athene=DEBUG
|
||||||
server.port=8080
|
server.port=8080
|
||||||
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
||||||
|
spring.codec.max-in-memory-size=50MB
|
||||||
joinfaces.primefaces.theme=afterwork
|
joinfaces.primefaces.theme=afterwork
|
||||||
joinfaces.primefaces.font-awesome=true
|
joinfaces.primefaces.font-awesome=true
|
||||||
time-series.db-path=time-series-db
|
time-series.db-path=time-series-db
|
||||||
|
Loading…
Reference in New Issue
Block a user