Browse Source

Initial commit

pull/1/head
slixe 1 year ago
commit
ff5539017b
19 changed files with 1019 additions and 0 deletions
  1. +12
    -0
      .gitignore
  2. +37
    -0
      build.gradle
  3. +11
    -0
      config/routes.groovy
  4. BIN
      gradle/wrapper/gradle-wrapper.jar
  5. +5
    -0
      gradle/wrapper/gradle-wrapper.properties
  6. +188
    -0
      gradlew
  7. +100
    -0
      gradlew.bat
  8. +10
    -0
      settings.gradle
  9. +41
    -0
      src/main/java/fr/slixe/benchmarks/App.java
  10. +70
    -0
      src/main/java/fr/slixe/benchmarks/Benchmark.java
  11. +12
    -0
      src/main/java/fr/slixe/benchmarks/JsonIgnore.java
  12. +18
    -0
      src/main/java/fr/slixe/benchmarks/Main.java
  13. +31
    -0
      src/main/java/fr/slixe/benchmarks/MyModule.java
  14. +11
    -0
      src/main/java/fr/slixe/benchmarks/http/InvalidParameterException.java
  15. +189
    -0
      src/main/java/fr/slixe/benchmarks/http/SparkHttpServer.java
  16. +103
    -0
      src/main/java/fr/slixe/benchmarks/http/controller/MainController.groovy
  17. +49
    -0
      src/main/java/fr/slixe/benchmarks/serialization/BenchmarkAdapter.java
  18. +128
    -0
      src/main/java/fr/slixe/benchmarks/service/BenchmarkService.java
  19. +4
    -0
      src/main/resources/config.default.json

+ 12
- 0
.gitignore View File

@@ -0,0 +1,12 @@
# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build
/.project
/.classpath
/benchmarks-confirmed.json
/benchmarks-unconfirmed.json
/benchmarks.json
/config.json
/.gitignore

+ 37
- 0
build.gradle View File

@@ -0,0 +1,37 @@
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'eclipse'

// Groovy interop
sourceSets.main.java.srcDirs = []
sourceSets.main.groovy.srcDirs += ["src/main/java"]

repositories {
maven {
url 'http://wytrem.github.io/maven'
}

maven {
url 'https://paladin-framework.github.io/maven'
}
mavenCentral()
}

dependencies {
implementation(
'com.sparkjava:spark-core:2.8.0',
'net.sf.trove4j:trove4j:3.0.3',
'com.google.code.gson:gson:2.8.5',
//'com.google.guava:guava:27.0.1-jre',
'com.mashape.unirest:unirest-java:1.4.9',
'org.apache.commons:commons-lang3:3.8.1',
'org.apache.logging.log4j:log4j-core:2.10.0'
)
implementation('fr.litarvan.paladin:paladin-framework:1.0.0') {
exclude group: 'org.apache.httpcomponents', module: 'httpcore-nio'
exclude group: 'org.apache.logging.log4j', module: 'log4j-core'
}
}

+ 11
- 0
config/routes.groovy View File

@@ -0,0 +1,11 @@
package config;
group '/api', {
get '/benchmarks'
get '/unconfirmedBenchmarks'
post '/submit'
post '/confirm'
post '/delete'
}, [
action: 'main'
]

BIN
gradle/wrapper/gradle-wrapper.jar View File


+ 5
- 0
gradle/wrapper/gradle-wrapper.properties View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

+ 188
- 0
gradlew View File

@@ -0,0 +1,188 @@
#!/usr/bin/env sh

#
# Copyright 2015 the original author or 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
#
# http://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 UN*X
##
##############################################################################

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$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 "$*"
}

die () {
echo
echo "$*"
echo
exit 1
}

# 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
;;
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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`

# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option

if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi

# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi

exec "$JAVACMD" "$@"

+ 100
- 0
gradlew.bat View File

@@ -0,0 +1,100 @@
@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 http://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 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 init
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 init
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
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
: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 %CMD_LINE_ARGS%
: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

+ 10
- 0
settings.gradle View File

@@ -0,0 +1,10 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/5.4/userguide/multi_project_builds.html
*/

rootProject.name = 'DERO Benchmarks'

+ 41
- 0
src/main/java/fr/slixe/benchmarks/App.java View File

@@ -0,0 +1,41 @@
package fr.slixe.benchmarks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import fr.litarvan.paladin.OnStart;
import fr.litarvan.paladin.OnStop;
import fr.litarvan.paladin.PaladinApp;
import fr.slixe.benchmarks.service.BenchmarkService;
import spark.Spark;
@PaladinApp(name = "DERO Benchmarks", version = App.VERSION, author = "Slixe")
public class App
{
public static final String VERSION = "0.0.1";
private static final Logger log = LoggerFactory.getLogger("DERO Benchmarks");
@Inject
private BenchmarkService benchmarkService;
@OnStart
public void start()
{
log.info("Loading benchmarks...");
benchmarkService.loadBenchmarks();
}
@OnStop
public void stop()
{
log.info("Shutting down http service...");
Spark.stop();
log.info("Saving benchmarks...");
benchmarkService.saveBenchmarks();
}
}

+ 70
- 0
src/main/java/fr/slixe/benchmarks/Benchmark.java View File

@@ -0,0 +1,70 @@
package fr.slixe.benchmarks;

public class Benchmark {

private int id;
private Vendor vendor; //AMD
private String model; //Ryzen 5 3600X
private long hashrate; //550h/s
private String minerVersion; //XMRig 5.9.0
private String owner; //Owner
private long timestamp; //Submitted on 08/03/2020
public Benchmark(int id, Vendor vendor, String model, long hashrate, String minerVersion, String owner, long timestamp)
{
this.id = id;
this.vendor = vendor;
this.model = model;
this.hashrate = hashrate;
this.minerVersion = minerVersion;
this.owner = owner;
this.timestamp = timestamp;
}

public int getId()
{
return id;
}

public Vendor getVendor()
{
return vendor;
}

public String getModel()
{
return model;
}

public long getHashrate()
{
return hashrate;
}
public String getMinerVersion()
{
return minerVersion;
}

public String getOwner()
{
return owner;
}

public long getTimestamp()
{
return timestamp;
}
@Override
public String toString()
{
return String.format("Benchmark[vendor=%s, model=%s, hashrate=%d, owner=%s, timestamp=%d]", vendor.name(), model, hashrate, owner, timestamp);
}

public static enum Vendor {
AMD,
NVIDIA,
INTEL
}
}

+ 12
- 0
src/main/java/fr/slixe/benchmarks/JsonIgnore.java View File

@@ -0,0 +1,12 @@
package fr.slixe.benchmarks;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonIgnore
{
}

+ 18
- 0
src/main/java/fr/slixe/benchmarks/Main.java View File

@@ -0,0 +1,18 @@
package fr.slixe.benchmarks;
import fr.litarvan.paladin.Paladin;
import fr.litarvan.paladin.PaladinBuilder;
import fr.slixe.benchmarks.http.SparkHttpServer;
public class Main
{
public static void main(String[] args)
{
Paladin paladin = PaladinBuilder.create(App.class)
.addModule(new MyModule())
.loadCommandLineArguments(args)
.build();
paladin.start(new SparkHttpServer(paladin, paladin.getConfig().get("port", int.class)));
}
}

+ 31
- 0
src/main/java/fr/slixe/benchmarks/MyModule.java View File

@@ -0,0 +1,31 @@
package fr.slixe.benchmarks;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.AbstractModule;
import fr.slixe.benchmarks.serialization.BenchmarkAdapter;
public class MyModule extends AbstractModule
{
@Override
protected void configure()
{
bind(Gson.class).toInstance(new GsonBuilder().registerTypeAdapter(Benchmark.class, new BenchmarkAdapter()).setPrettyPrinting().addSerializationExclusionStrategy(new ExclusionStrategy()
{
@Override
public boolean shouldSkipField(FieldAttributes f)
{
return f.getAnnotation(JsonIgnore.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz)
{
return false;
}
}).create());
}
}

+ 11
- 0
src/main/java/fr/slixe/benchmarks/http/InvalidParameterException.java View File

@@ -0,0 +1,11 @@
package fr.slixe.benchmarks.http;
import fr.litarvan.paladin.http.routing.RequestException;
public class InvalidParameterException extends RequestException
{
public InvalidParameterException(String message)
{
super("Invalid parameter : " + message);
}
}

+ 189
- 0
src/main/java/fr/slixe/benchmarks/http/SparkHttpServer.java View File

@@ -0,0 +1,189 @@
package fr.slixe.benchmarks.http;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;
import fr.litarvan.paladin.Paladin;
import fr.litarvan.paladin.http.Cookie;
import fr.litarvan.paladin.http.Header;
import fr.litarvan.paladin.http.HeaderPair;
import fr.litarvan.paladin.http.HttpMethod;
import fr.litarvan.paladin.http.Request;
import fr.litarvan.paladin.http.Response;
import fr.litarvan.paladin.http.server.PaladinHttpServer;
import spark.Spark;
public class SparkHttpServer implements PaladinHttpServer
{
// TODO: Replace with real web server
private Paladin paladin;
private int port;
private boolean isRunning;
public SparkHttpServer(Paladin paladin, int port)
{
this.paladin = paladin;
this.port = port;
}
@Override
public void start() throws IOException
{
Spark.port(port);
Spark.threadPool(15);
Spark.before((request, originalResponse) -> {
Response response = new Response();
paladin.execute(createRequest(request, response), response);
applyResponse(originalResponse, response);
Spark.halt();
});
Spark.awaitInitialization();
this.isRunning = true;
}
protected Request createRequest(spark.Request request, Response response)
{
String[] headerNames = request.headers().toArray(new String[0]);
Header[] headers = new Header[headerNames.length];
for (int i = 0; i < headerNames.length; i++) {
headers[i] = new Header(headerNames[i], request.headers(headerNames[i]));
}
String[] queryParams = request.queryParams().toArray(new String[0]);
Map<String, String> params = new HashMap<>(request.params());
for (String queryParam : queryParams) {
params.put(queryParam, request.queryParams(queryParam));
}
String[] cookieNames = request.cookies().keySet().toArray(new String[0]);
Cookie[] cookies = new Cookie[cookieNames.length];
for (int i = 0; i < cookieNames.length; i++) {
cookies[i] = new Cookie(cookieNames[i], request.cookie(cookieNames[i]));
}
Header contentType = null;
for (Header header : headers)
{
if (header.getName().equalsIgnoreCase(Header.CONTENT_TYPE))
{
contentType = header;
break;
}
}
if (contentType != null && Header.CONTENT_TYPE_FORM_URL_ENCODED.equals(contentType.getValue()))
{
extractParams(params, new String(request.bodyAsBytes(), Charset.defaultCharset()));
}
return new Request(paladin, request.ip(), HttpMethod.valueOf(request.requestMethod()), request.uri(), headers, request.bodyAsBytes(), params, cookies, response);
}
protected void extractParams(Map<String, String> params, String query)
{
for (String param : query.split("&"))
{
String[] split = param.split("=");
try
{
params.put(URLDecoder.decode(split[0], Charset.defaultCharset().name()), split.length > 1 ? URLDecoder.decode(split[1], Charset.defaultCharset().name()) : "");
}
catch (UnsupportedEncodingException e)
{
// Can't happen
}
}
}
protected void applyResponse(spark.Response sparkResponse, Response response)
{
for (Header header : response.getHeaders()) {
String value = "";
if (header.getValue() != null && !header.getValue().isEmpty())
{
value = header.getValue();
}
else if (header.getPairs() != null)
{
for (int i1 = 0; i1 < header.getPairs().size(); i1++)
{
HeaderPair pair = header.getPairs().get(i1);
try
{
value += pair.getName() + "=" + URLEncoder.encode(pair.getValue(), Charset.defaultCharset().name()) + (i1 + 1 < header.getPairs().size() ? "; " : "");
}
catch (UnsupportedEncodingException ignored)
{
// Can't happen
}
}
}
sparkResponse.header(header.getName(), value);
}
for (Cookie cookie : response.getCookies()) {
// TODO: Cookie params ? (& Dans Paladin)
sparkResponse.cookie(cookie.getName(), cookie.getValue());
}
sparkResponse.status(response.getCode());
try {
sparkResponse.raw().getOutputStream().write(response.getContent());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void loadSSLCert(File file, char[] secret) throws GeneralSecurityException, IOException
{
// TODO: Currently not used in Paladin
}
@Override
public synchronized void waitFor() throws InterruptedException
{
while (this.isRunning) {
this.wait();
}
}
@Override
public void shutdown()
{
this.isRunning = false;
Spark.stop();
}
@Override
public String getAddress()
{
try {
return InetAddress.getLocalHost().getHostAddress() + ":" + port;
} catch (UnknownHostException e) {
return ":" + port;
}
}
}

+ 103
- 0
src/main/java/fr/slixe/benchmarks/http/controller/MainController.groovy View File

@@ -0,0 +1,103 @@
package fr.slixe.benchmarks.http.controller;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.inject.Inject;

import fr.litarvan.paladin.http.Controller;
import fr.litarvan.paladin.http.routing.RequestParams;
import fr.slixe.benchmarks.Benchmark;
import fr.slixe.benchmarks.Benchmark.Vendor
import fr.slixe.benchmarks.service.BenchmarkService;

public class MainController extends Controller {

private static final Logger log = LoggerFactory.getLogger("DERO HTTP Controller")

@Inject
private BenchmarkService benchmarkService

@Inject
private Gson gson

/**
* accessible from: api/benchmarks
* @return all confirmed benchmarks
*/
def benchmarks()
{
log.debug("Benchmarks requested")

return benchmarkService.getBenchmarks()
}

def unconfirmedBenchmarks()
{
log.debug("Unconfirmed Benchmarks requested")

return benchmarkService.getUnconfirmedBenchmarks()
}
/** Submit a benchmark
* @param Vendor vendor (AMD/INTEL/NVIDIA)
* @param String model (Ryzen 5 3600X)
* @param long hashrate (in h/s)
* @param String minerVersion (XMRig 5.9.0)
* @param String owner (Slixe)
*/
@RequestParams(required = ["vendor", "model", "hashrate", "minerVersion", "owner"])
def submit(Vendor vendor, String model, long hashrate, String minerVersion, String owner)
{
log.debug("A new benchmark has been submitted!")
Benchmark benchmark = new Benchmark(benchmarkService.lastBenchId(), vendor, model, hashrate, minerVersion, owner)
benchmarkService.addUnconfirmedBenchmarks(benchmark)

[
success: true,
message: "Your benchmark has been submitted! It will be reviewed soon. Thanks.",
result: null
]
}

/** Confirm a submitted benchmark.
* accessible from: api/confirm
* @param int benchID
*/
@RequestParams(required = ["benchID"])
def confirm(int benchID) //TODO Add auth
{
log.debug("Confirmation of Benchmark $benchID")
def result = benchmarkService.confirmBenchmark(benchID)

[
success: result,
message: result ? "The benchmark $benchID is now confirmed!" : "The benchmark $benchID was not found!",
result: null
]
}

/** Delete a benchmark using the unique ID.
* accessible from: api/delete
* @param int benchID
*/
@RequestParams(required = ["benchID"])
def delete(int benchID) //TODO Add auth
{
log.debug("Removing Benchmark $benchID")
def result = benchmarkService.removeBenchmark(benchID)

[
success: result,
message: result ? "The benchmark $benchID has been removed!" : "Benchmark $benchID not found!",
result: null
]
}
}

+ 49
- 0
src/main/java/fr/slixe/benchmarks/serialization/BenchmarkAdapter.java View File

@@ -0,0 +1,49 @@
package fr.slixe.benchmarks.serialization;

import java.lang.reflect.Type;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import fr.slixe.benchmarks.Benchmark;
import fr.slixe.benchmarks.Benchmark.Vendor;

public class BenchmarkAdapter implements JsonSerializer<Benchmark>, JsonDeserializer<Benchmark> {

@Override
public JsonElement serialize(Benchmark src, Type typeOfSrc, JsonSerializationContext context)
{
JsonObject json = new JsonObject();

json.addProperty("id", src.getId());
json.addProperty("vendor", src.getVendor().name());
json.addProperty("model", src.getModel());
json.addProperty("hashrate", src.getHashrate());
json.addProperty("minerVersion", src.getMinerVersion());
json.addProperty("owner", src.getOwner());
json.addProperty("timestamp", src.getTimestamp());

return json;
}

@Override
public Benchmark deserialize(JsonElement jsonElement, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
JsonObject json = jsonElement.getAsJsonObject();

int id = json.get("id").getAsInt();
Vendor vendor = Vendor.valueOf(json.get("vendor").getAsString());
String model = json.get("model").getAsString();
long hashrate = json.get("hashrate").getAsLong();
String minerVersion = json.get("minerVersion").getAsString();
String owner = json.get("owner").getAsString();
long timestamp = json.get("timestamp").getAsLong();

return new Benchmark(id, vendor, model, hashrate, minerVersion, owner, timestamp);
}
}

+ 128
- 0
src/main/java/fr/slixe/benchmarks/service/BenchmarkService.java View File

@@ -0,0 +1,128 @@
package fr.slixe.benchmarks.service;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import fr.slixe.benchmarks.Benchmark;

@Singleton
public class BenchmarkService {

private static final Type BENCHMARK_TYPE = new TypeToken<List<Benchmark>>(){}.getType();
private static final Logger log = LoggerFactory.getLogger("DERO Benchmark Service");

private final List<Benchmark> confirmedBenchmarks = new ArrayList<>();
private final List<Benchmark> unconfirmedBenchmarks = new ArrayList<>();
private final File confirmedBenchmarksFile = new File("benchmarks-confirmed.json");
private final File unconfirmedBenchmarksFile = new File("benchmarks-unconfirmed.json");
@Inject
private Gson gson;
private void loadBenchmarks(File file, List<Benchmark> benchmarks)
{
if (!file.exists())
try {
file.createNewFile();
saveBenchmarks(file, benchmarks);
} catch (IOException e) {
log.error(e.getMessage());
}
else
try {
JsonReader jsonReader = new JsonReader(new FileReader(file));
benchmarks.addAll(gson.fromJson(jsonReader, BENCHMARK_TYPE));
log.info(benchmarks.toString());
jsonReader.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}

private void saveBenchmarks(File file, List<Benchmark> benchmarks)
{
try (FileWriter fileWriter = new FileWriter(file)) {
gson.toJson(benchmarks, BENCHMARK_TYPE, fileWriter);
} catch (IOException e) {
log.error(e.getMessage());
}
}
public void loadBenchmarks()
{
loadBenchmarks(this.confirmedBenchmarksFile, this.confirmedBenchmarks);
loadBenchmarks(this.unconfirmedBenchmarksFile, this.unconfirmedBenchmarks);
}

public void saveBenchmarks()
{
saveBenchmarks(this.confirmedBenchmarksFile, this.confirmedBenchmarks);
saveBenchmarks(this.unconfirmedBenchmarksFile, this.unconfirmedBenchmarks);
}
public boolean addUnconfirmedBenchmarks(Benchmark benchmark)
{
return this.unconfirmedBenchmarks.add(benchmark);
}

public boolean confirmBenchmark(int benchID)
{
Optional<Benchmark> opt = this.unconfirmedBenchmarks.parallelStream().filter(e -> e.getId() == benchID).findFirst();

if (opt.isPresent()) {
Benchmark benchmark = opt.get();
this.unconfirmedBenchmarks.remove(benchmark);
this.confirmedBenchmarks.add(benchmark);
}
return opt.isPresent();
}

public boolean removeBenchmark(int benchID)
{
boolean result = this.unconfirmedBenchmarks.removeIf(e -> e.getId() == benchID);

if (!result) {
result = this.confirmedBenchmarks.removeIf(e -> e.getId() == benchID);
}

return result;
}
public int lastBenchId()
{
if (this.confirmedBenchmarks.size() == 0 && this.unconfirmedBenchmarks.size() == 0)
return 0;

int a = this.confirmedBenchmarks.get(this.confirmedBenchmarks.size() - 1).getId() + 1;
int b = this.unconfirmedBenchmarks.get(this.unconfirmedBenchmarks.size() - 1).getId() + 1;

return a < b ? b : a;
}
public List<Benchmark> getBenchmarks()
{
return this.confirmedBenchmarks;
}
public List<Benchmark> getUnconfirmedBenchmarks()
{
return this.unconfirmedBenchmarks;
}
}

+ 4
- 0
src/main/resources/config.default.json View File

@@ -0,0 +1,4 @@
{
"port": 8080,
"password": "HelloWorld123"
}

Loading…
Cancel
Save