From 94f50deda16154895028bb7cf306f4b8b00dfed1 Mon Sep 17 00:00:00 2001 From: Sandra Date: Tue, 17 May 2022 10:09:36 +0200 Subject: [PATCH] Migrate backend to n8n --- backend/api/build.gradle | 10 - .../okaeri/timings/api/IndexController.java | 13 - .../timings/api/TimingsApplication.java | 12 - .../timings/api/security/SecurityConfig.java | 36 --- .../timings/api/v1/ParseController.java | 98 -------- .../api/src/main/resources/application.yml | 41 --- .../test/java/eu/okaeri/timings/api/.gitkeep | 0 backend/api/src/test/resources/.gitkeep | 0 backend/build.gradle | 39 --- backend/dataaccess/build.gradle | 20 -- backend/dataaccess/src/main/java/.gitkeep | 0 .../dataaccess/util/UUID6Generator.java | 38 --- .../dataaccess/src/main/resources/.gitkeep | 0 backend/function.js | 81 ++++++ .../gradle/wrapper/gradle-wrapper.properties | 5 - backend/gradlew | 234 ------------------ backend/gradlew.bat | 89 ------- backend/settings.gradle | 4 - backend/timings_okaeri_cloud_v1_parse.json | 59 +++++ frontend/.env.development | 2 +- frontend/.env.production | 4 +- 21 files changed, 143 insertions(+), 642 deletions(-) delete mode 100644 backend/api/build.gradle delete mode 100644 backend/api/src/main/java/eu/okaeri/timings/api/IndexController.java delete mode 100644 backend/api/src/main/java/eu/okaeri/timings/api/TimingsApplication.java delete mode 100644 backend/api/src/main/java/eu/okaeri/timings/api/security/SecurityConfig.java delete mode 100644 backend/api/src/main/java/eu/okaeri/timings/api/v1/ParseController.java delete mode 100644 backend/api/src/main/resources/application.yml delete mode 100644 backend/api/src/test/java/eu/okaeri/timings/api/.gitkeep delete mode 100644 backend/api/src/test/resources/.gitkeep delete mode 100644 backend/build.gradle delete mode 100644 backend/dataaccess/build.gradle delete mode 100644 backend/dataaccess/src/main/java/.gitkeep delete mode 100644 backend/dataaccess/src/main/java/eu/okaeri/timings/dataaccess/util/UUID6Generator.java delete mode 100644 backend/dataaccess/src/main/resources/.gitkeep create mode 100644 backend/function.js delete mode 100644 backend/gradle/wrapper/gradle-wrapper.properties delete mode 100644 backend/gradlew delete mode 100644 backend/gradlew.bat delete mode 100644 backend/settings.gradle create mode 100644 backend/timings_okaeri_cloud_v1_parse.json diff --git a/backend/api/build.gradle b/backend/api/build.gradle deleted file mode 100644 index e244bf0..0000000 --- a/backend/api/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -dependencies { - - implementation project(':dataaccess') - - annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-security' - - implementation 'org.springdoc:springdoc-openapi-ui:1.6.4' -} diff --git a/backend/api/src/main/java/eu/okaeri/timings/api/IndexController.java b/backend/api/src/main/java/eu/okaeri/timings/api/IndexController.java deleted file mode 100644 index 3bef1bf..0000000 --- a/backend/api/src/main/java/eu/okaeri/timings/api/IndexController.java +++ /dev/null @@ -1,13 +0,0 @@ -package eu.okaeri.timings.api; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -public class IndexController { - - @RequestMapping - public String index() { - return "redirect:/swagger-ui"; - } -} diff --git a/backend/api/src/main/java/eu/okaeri/timings/api/TimingsApplication.java b/backend/api/src/main/java/eu/okaeri/timings/api/TimingsApplication.java deleted file mode 100644 index a73093b..0000000 --- a/backend/api/src/main/java/eu/okaeri/timings/api/TimingsApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -package eu.okaeri.timings.api; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class TimingsApplication { - - public static void main(String[] args) { - SpringApplication.run(TimingsApplication.class, args); - } -} diff --git a/backend/api/src/main/java/eu/okaeri/timings/api/security/SecurityConfig.java b/backend/api/src/main/java/eu/okaeri/timings/api/security/SecurityConfig.java deleted file mode 100644 index 9d83afb..0000000 --- a/backend/api/src/main/java/eu/okaeri/timings/api/security/SecurityConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package eu.okaeri.timings.api.security; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; -import org.springframework.web.filter.CorsFilter; - -import java.util.Arrays; -import java.util.List; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.httpBasic().disable(); - http.csrf().disable(); - } - - @Bean - public CorsFilter corsFilter() { - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - CorsConfiguration config = new CorsConfiguration(); - config.setAllowCredentials(false); - config.setAllowedOrigins(List.of("*")); - config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept")); - config.setAllowedMethods(List.of("*")); - source.registerCorsConfiguration("/**", config); - return new CorsFilter(source); - } -} diff --git a/backend/api/src/main/java/eu/okaeri/timings/api/v1/ParseController.java b/backend/api/src/main/java/eu/okaeri/timings/api/v1/ParseController.java deleted file mode 100644 index 9f23566..0000000 --- a/backend/api/src/main/java/eu/okaeri/timings/api/v1/ParseController.java +++ /dev/null @@ -1,98 +0,0 @@ -package eu.okaeri.timings.api.v1; - -import lombok.SneakyThrows; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.time.Instant; -import java.util.*; -import java.util.stream.Collectors; - -@RestController -@RequestMapping("/v1/parse") -public class ParseController { - - @SneakyThrows - @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity parse(@RequestPart("file") MultipartFile file) { - - Instant start = Instant.now(); - String content = new String(file.getBytes(), StandardCharsets.UTF_8); - String[] lines = content.split("\r?\n"); - - Map metadata = new LinkedHashMap<>(); - List header = null; - List> records = new ArrayList<>(); - - for (String line : lines) { - - // metadata - if (line.startsWith("#")) { - if (!line.contains(":")) { - continue; - } - String[] parts = line.substring(1).split(":", 2); - if (parts.length != 2) { - return ResponseEntity.badRequest().body(Map.of("error", "Cannot parse metadata: '" + line + "'")); - } - String key = parts[0].trim().toLowerCase(Locale.ROOT); - String value = parts[1].trim(); - metadata.put(key, value); - continue; - } - - // header - if (header == null) { - String[] parts = line.split(","); - if (parts.length < 2) { - return ResponseEntity.badRequest().body(Map.of("error", "Cannot parse header: '" + line + "'")); - } - header = Arrays.asList(parts); - continue; - } - - // data - String[] parts = line.split(","); - if (parts.length != header.size()) { - return ResponseEntity.badRequest().body(Map.of("error", "Cannot parse record: '" + line + "'")); - } - - try { - records.add(Arrays.stream(parts) - .map(value -> { - try { - return new BigDecimal(value); - } catch (Exception exception) { - throw new RuntimeException("Cannot parse value: '" + value + "' from record '" + line + "'"); - } - }) - .collect(Collectors.toList())); - } catch (Exception exception) { - return ResponseEntity.badRequest().body(Map.of("error", exception.getMessage())); - } - } - - if (header == null || records.size() < 2) { - return ResponseEntity.badRequest().body(Map.of("error", "Invalid report")); - } - - Map stats = Map.of( - "parseTime", (Duration.between(start, Instant.now())) - ); - - return ResponseEntity.ok(Map.of( - "meta", metadata, - "header", header, - "data", records, - "stats", stats - )); - } -} diff --git a/backend/api/src/main/resources/application.yml b/backend/api/src/main/resources/application.yml deleted file mode 100644 index ad95c23..0000000 --- a/backend/api/src/main/resources/application.yml +++ /dev/null @@ -1,41 +0,0 @@ -server: - address: 127.0.0.1 - port: 8081 - error: - whitelabel: - enabled: false - servlet: - context-path: / - # tomcat: - # internal-proxies: "" - forward-headers-strategy: native - -springdoc: - api-docs: - path: /api-docs - swagger-ui: - path: /swagger-ui - tags-sorter: alpha - operations-sorter: alpha - default-produces-media-type: "application/json" - -spring: - servlet: - multipart: - enabled: true - max-file-size: 1MB - max-request-size: 1MB - redis: - host: 127.0.0.1 - port: 6379 - # password: "" - datasource: - url: jdbc:h2:file:./timings;AUTO_SERVER=TRUE - username: demo - password: password - driverClassName: org.h2.Driver - jpa: - hibernate: - ddl-auto: update - show-sql: true - database-platform: org.hibernate.dialect.H2Dialect diff --git a/backend/api/src/test/java/eu/okaeri/timings/api/.gitkeep b/backend/api/src/test/java/eu/okaeri/timings/api/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/backend/api/src/test/resources/.gitkeep b/backend/api/src/test/resources/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/backend/build.gradle b/backend/build.gradle deleted file mode 100644 index 7c23113..0000000 --- a/backend/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -plugins { - id 'org.springframework.boot' version '2.6.1' - id 'io.spring.dependency-management' version '1.0.11.RELEASE' - id 'java' -} - -allprojects { - - group = 'eu.okaeri.timings' - version = '0.0.1-SNAPSHOT' - - repositories { - mavenCentral() - } -} - -subprojects { - - apply plugin: 'io.spring.dependency-management' - apply plugin: 'org.springframework.boot' - apply plugin: 'java' - - sourceCompatibility = '17' - - dependencies { - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - } -} - -configurations { - compileOnly { - extendsFrom annotationProcessor - } -} - -bootJar { - enabled = false -} diff --git a/backend/dataaccess/build.gradle b/backend/dataaccess/build.gradle deleted file mode 100644 index 4f34b88..0000000 --- a/backend/dataaccess/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -dependencies { - - implementation 'org.springframework.boot:spring-boot-starter-cache' - implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'org.springframework.boot:spring-boot-starter-data-redis' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - - runtimeOnly 'mysql:mysql-connector-java' - runtimeOnly 'com.h2database:h2' - - implementation 'com.github.f4b6a3:uuid-creator:4.3.1' -} - -bootJar { - enabled = false -} - -jar { - enabled = true -} diff --git a/backend/dataaccess/src/main/java/.gitkeep b/backend/dataaccess/src/main/java/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/backend/dataaccess/src/main/java/eu/okaeri/timings/dataaccess/util/UUID6Generator.java b/backend/dataaccess/src/main/java/eu/okaeri/timings/dataaccess/util/UUID6Generator.java deleted file mode 100644 index 5c979a9..0000000 --- a/backend/dataaccess/src/main/java/eu/okaeri/timings/dataaccess/util/UUID6Generator.java +++ /dev/null @@ -1,38 +0,0 @@ -package eu.okaeri.timings.dataaccess.util; - -import com.github.f4b6a3.uuid.UuidCreator; -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.id.UUIDGenerator; -import org.hibernate.service.ServiceRegistry; -import org.hibernate.type.Type; -import org.hibernate.type.descriptor.java.UUIDTypeDescriptor; - -import java.io.Serializable; -import java.util.Properties; -import java.util.UUID; - -public class UUID6Generator extends UUIDGenerator { - - private UUIDTypeDescriptor.ValueTransformer valueTransformer; - - @Override - public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException { - if (UUID.class.isAssignableFrom(type.getReturnedClass())) { - this.valueTransformer = UUIDTypeDescriptor.PassThroughTransformer.INSTANCE; - } else if (String.class.isAssignableFrom(type.getReturnedClass())) { - this.valueTransformer = UUIDTypeDescriptor.ToStringTransformer.INSTANCE; - } else { - if (!byte[].class.isAssignableFrom(type.getReturnedClass())) { - throw new HibernateException("Unanticipated return type [" + type.getReturnedClass().getName() + "] for UUID conversion"); - } - this.valueTransformer = UUIDTypeDescriptor.ToBytesTransformer.INSTANCE; - } - } - - @Override - public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { - return this.valueTransformer.transform(UuidCreator.getTimeOrderedWithRandom()); - } -} diff --git a/backend/dataaccess/src/main/resources/.gitkeep b/backend/dataaccess/src/main/resources/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/backend/function.js b/backend/function.js new file mode 100644 index 0000000..8eb0547 --- /dev/null +++ b/backend/function.js @@ -0,0 +1,81 @@ +const parseReport = (text) => { + + const start = new Date(); + const lines = text.split(/\r?\n/); + + const metadata = {}; + let header = null; + const records = []; + + for (const line of lines) { + + // empty + if (!line) { + continue + } + + // metadata + if (line.startsWith("#")) { + if (!line.includes(":")) { + continue; + } + const parts = line.substring(1).split(":", 2); + if (parts.length !== 2) { + return {error: `Invalid metadata: '${line}'`}; + } + const key = parts[0].trim().toLowerCase(); + metadata[key] = parts[1].trim(); + continue; + } + + // header + if (header === null) { + const parts = line.split(","); + if (parts.length < 2) { + return {error: `Invalid header: '${line}'`}; + } + header = parts; + continue; + } + + // data + const parts = line.split(","); + if (parts.length !== header.length) { + return {error: `Invalid record: '${line}'`}; + } + + records.push(parts.map(value => { + const floatValue = parseFloat(value); + if (Number.isNaN(floatValue)) { + return {error: `Invalid number '${value}' in: '${line}'`} + } + return floatValue; + })); + } + + if (header === null || records.length < 2) { + return {error: "Invalid report"}; + } + + return { + meta: metadata, + header: header, + data: records, + stats: { + parseTime: `PT${((new Date() - start) / 1000)}S` + } + } +}; + +if (items.length === 0) { + items[0].json = {error: "No report file found in the request."}; +} else if (items.length > 1) { + items[0].json = {error: "More than one file found in the request."} +} else { + const data = items[0].binary.file.data; + const text = Buffer.from(data, "base64").toString("utf8"); + items[0].json = parseReport(text) +} + +// noinspection JSAnnotator +return items; diff --git a/backend/gradle/wrapper/gradle-wrapper.properties b/backend/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 84d1f85..0000000 --- a/backend/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/backend/gradlew b/backend/gradlew deleted file mode 100644 index 1b6c787..0000000 --- a/backend/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/backend/gradlew.bat b/backend/gradlew.bat deleted file mode 100644 index 107acd3..0000000 --- a/backend/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/backend/settings.gradle b/backend/settings.gradle deleted file mode 100644 index 7c91eab..0000000 --- a/backend/settings.gradle +++ /dev/null @@ -1,4 +0,0 @@ -rootProject.name = 'backend' - -include 'dataaccess' -include 'api' diff --git a/backend/timings_okaeri_cloud_v1_parse.json b/backend/timings_okaeri_cloud_v1_parse.json new file mode 100644 index 0000000..dfd0993 --- /dev/null +++ b/backend/timings_okaeri_cloud_v1_parse.json @@ -0,0 +1,59 @@ +{ + "name": "timings.okaeri.cloud/v1/parse", + "nodes": [ + { + "parameters": {}, + "name": "Start", + "type": "n8n-nodes-base.start", + "typeVersion": 1, + "position": [ + 240, + 300 + ] + }, + { + "parameters": { + "httpMethod": "POST", + "path": "timings-api.okaeri.cloud/v1/parse", + "responseMode": "lastNode", + "options": {} + }, + "name": "Webhook", + "type": "n8n-nodes-base.webhook", + "typeVersion": 1, + "position": [ + 740, + 320 + ], + "webhookId": "a63ac908-a85d-4581-adbf-a58ad5c05ed4" + }, + { + "parameters": { + "functionCode": "const parseReport = (text) => {\n\n const start = new Date();\n const lines = text.split(/\\r?\\n/);\n\n const metadata = {};\n let header = null;\n const records = [];\n\n for (const line of lines) {\n\n // empty\n if (!line) {\n continue\n }\n\n // metadata\n if (line.startsWith(\"#\")) {\n if (!line.includes(\":\")) {\n continue;\n }\n const parts = line.substring(1).split(\":\", 2);\n if (parts.length !== 2) {\n return {error: `Invalid metadata: '${line}'`};\n }\n const key = parts[0].trim().toLowerCase();\n metadata[key] = parts[1].trim();\n continue;\n }\n\n // header\n if (header === null) {\n const parts = line.split(\",\");\n if (parts.length < 2) {\n return {error: `Invalid header: '${line}'`};\n }\n header = parts;\n continue;\n }\n\n // data\n const parts = line.split(\",\");\n if (parts.length !== header.length) {\n return {error: `Invalid record: '${line}'`};\n }\n\n records.push(parts.map(value => {\n const floatValue = parseFloat(value);\n if (Number.isNaN(floatValue)) {\n return {error: `Invalid number '${value}' in: '${line}'`}\n }\n return floatValue;\n }));\n }\n\n if (header === null || records.length < 2) {\n return {error: \"Invalid report\"};\n }\n\n return {\n meta: metadata,\n header: header,\n data: records,\n stats: {\n parseTime: `PT${((new Date() - start) / 1000)}S`\n }\n }\n};\n\nif (items.length === 0) {\n items[0].json = {error: \"No report file found in the request.\"};\n} else if (items.length > 1) {\n items[0].json = {error: \"More than one file found in the request.\"}\n} else {\n const data = items[0].binary.file.data;\n const text = Buffer.from(data, \"base64\").toString(\"utf8\");\n items[0].json = parseReport(text)\n}\n\nreturn items;\n" + }, + "name": "Function", + "type": "n8n-nodes-base.function", + "typeVersion": 1, + "position": [ + 960, + 320 + ] + } + ], + "connections": { + "Webhook": { + "main": [ + [ + { + "node": "Function", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": true, + "settings": {}, + "id": 1 +} \ No newline at end of file diff --git a/frontend/.env.development b/frontend/.env.development index f19d64b..0036146 100644 --- a/frontend/.env.development +++ b/frontend/.env.development @@ -1,2 +1,2 @@ -VUE_APP_URL=http://127.0.0.1:8080 +VUE_APP_URL=http://127.0.0.1:5678/webhook/timings-parse VUE_APP_API_URL=http://127.0.0.1:8081 diff --git a/frontend/.env.production b/frontend/.env.production index c0dae4c..86d9a21 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -1,2 +1,2 @@ -VUE_APP_URL=https://timings.okaeri.eu -VUE_APP_API_URL=https://timings-api.okaeri.eu +VUE_APP_URL=https://timings.okaeri.cloud +VUE_APP_API_URL=https://webhook.okaeri.cloud/timings-api.okaeri.cloud