[DEV] add test and update to archidata (does not work)

This commit is contained in:
Edouard DUPIN 2023-11-11 10:51:44 +01:00
parent 1897fac53a
commit 77de4e1fd7
27 changed files with 737 additions and 556 deletions

7
back/.checkstyle Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
<fileset name="all" enabled="true" check-config-name="Google Checks" local="false">
<file-match-pattern match-pattern="." include-pattern="true"/>
</fileset>
</fileset-config>

View File

@ -1,15 +1,15 @@
FROM maven:3.6.3-openjdk-16 AS build FROM maven:3-openjdk-18 AS build
COPY pom.xml /tmp/ COPY pom.xml /tmp/
COPY src /tmp/src/ COPY src /tmp/src/
WORKDIR /tmp/ WORKDIR /tmp/
RUN mvn clean compile assembly:single RUN mvn clean compile assembly:single
FROM bellsoft/liberica-openjdk-alpine:latest FROM bellsoft/liberica-openjdk-alpine:latest
ENV LANG=C.UTF-8 ENV LANG=C.UTF-8
# add wget to manage the health check...
RUN apk add --no-cache wget
RUN mkdir /application/ RUN mkdir /application/
COPY --from=build /tmp/out/maven/*.jar /application/application.jar COPY --from=build /tmp/out/maven/*.jar /application/application.jar

View File

@ -2,16 +2,24 @@ Generic backend for karusic in java
=================================== ===================================
mvn install mvn install
mvn compile
mvn package
// download all dependency in out/maven/dependency
mvn dependency:copy-dependencies
java -cp out/maven/kar-karusic-0.1.0.jar org.kar.karusic.WebLauncher
// create a single package jar // create a single package jar
mvn clean compile assembly:single mvn clean compile assembly:single
java -cp out/maven/karusic-0.1.0-jar-with-dependencies.jar org.kar.karideo.WebLauncher java -cp out/maven/karusic-0.1.0-jar-with-dependencies.jar org.kar.karusic.WebLauncher

View File

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_14">
<output url="file://$MODULE_DIR$/out/maven/classes" />
<output-test url="file://$MODULE_DIR$/out/maven/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/src" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/out/maven" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-multipart:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-common:2.32" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:osgi-resource-locator:1.0.3" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="library" name="Maven: org.jvnet.mimepull:mimepull:1.9.13" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.inject:jersey-hk2:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-locator:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2.external:aopalliance-repackaged:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-api:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-utils:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.25.0-GA" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2.external:jakarta.inject:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-http-server:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-http:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-framework:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-server:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-client:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-jaxb:2.32" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
<orderEntry type="library" name="Maven: jakarta.ws.rs:jakarta.ws.rs-api:2.1.6" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: javax.ws.rs:javax.ws.rs-api:2.1.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.xml.bind:jaxb-impl:2.3.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.7" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.servlet:jakarta.servlet-api:4.0.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.test-framework:jersey-test-framework-core:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-servlet-core:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-grizzly2-servlet:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-servlet:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.grizzly:grizzly-http-servlet:2.4.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.45" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-json-jackson:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.ext:jersey-entity-filtering:2.32" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.10.1" level="project" />
<orderEntry type="library" name="Maven: jakarta.activation:jakarta.activation-api:1.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.10" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.10" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:20.1.0" level="project" />
</component>
</module>

View File

@ -8,7 +8,6 @@
<maven.compiler.version>3.1</maven.compiler.version> <maven.compiler.version>3.1</maven.compiler.version>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<maven.dependency.version>3.1.1</maven.dependency.version> <maven.dependency.version>3.1.1</maven.dependency.version>
</properties> </properties>
<repositories> <repositories>
@ -17,7 +16,6 @@
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url> <url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</repository> </repository>
</repositories> </repositories>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>kangaroo-and-rabbit</groupId> <groupId>kangaroo-and-rabbit</groupId>
@ -28,19 +26,39 @@
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
<version>2.0.7</version> <version>2.0.7</version>
<!--<scope>test</scope>-->
</dependency> </dependency>
</dependencies> <!--
************************************************************
** TEST dependency **
************************************************************
-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build> <build>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test/src</testSourceDirectory> <testSourceDirectory>test/src</testSourceDirectory>
<directory>${project.basedir}/out/maven/</directory> <directory>${project.basedir}/out/maven/</directory>
<resources> <resources>
<resource> <resource>
<directory>src/resources</directory> <directory>src/resources</directory>
</resource> </resource>
</resources> </resources>
<testResources>
<testResource>
<directory>${basedir}/test/resources</directory>
</testResource>
</testResources>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -49,16 +67,15 @@
<configuration> <configuration>
<source>${maven.compiler.source}</source> <source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target> <target>${maven.compiler.target}</target>
<!--<encoding>${project.build.sourceEncoding}</encoding>-->
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId> <artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version> <version>1.4.0</version>
<configuration> <configuration>
<mainClass>org.kar.karusic.WebLauncher</mainClass> <mainClass>org.kar.karusic.WebLauncher</mainClass>
</configuration> </configuration>
</plugin> </plugin>
<!-- Create the source bundle --> <!-- Create the source bundle -->
<plugin> <plugin>
@ -80,27 +97,28 @@
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version> <version>3.0.0-M5</version>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
<configuration> <configuration>
<archive> <archive>
<manifest> <manifest>
<mainClass>fully.qualified.MainClass</mainClass> <mainClass>fully.qualified.MainClass</mainClass>
</manifest> </manifest>
</archive> </archive>
<descriptorRefs> <descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef> <descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs> </descriptorRefs>
</configuration> </configuration>
</plugin> </plugin>
<!-- Create coverage --> <!-- Create coverage -->
<!-- <!--
<plugin> <plugin>
<groupId>org.jacoco</groupId> <groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version> <version>0.8.10</version>
<executions> <executions>
<execution> <execution>
<id>prepare-agent</id>
<goals> <goals>
<goal>prepare-agent</goal> <goal>prepare-agent</goal>
</goals> </goals>
@ -112,6 +130,26 @@
<goal>report</goal> <goal>report</goal>
</goals> </goals>
</execution> </execution>
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions> </executions>
</plugin> </plugin>
--> -->
@ -125,6 +163,23 @@
<nohelp>true</nohelp> <nohelp>true</nohelp>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>exec-application</id>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.kar.karusic.WebLauncher</mainClass>
</configuration>
</plugin>
<!-- Check the style of the code --> <!-- Check the style of the code -->
<!-- <!--
<plugin> <plugin>
@ -182,5 +237,4 @@
</plugin> </plugin>
</plugins> </plugins>
</reporting> </reporting>
</project> </project>

View File

@ -1,174 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.kar</groupId>
<artifactId>karusic</artifactId>
<version>0.1.0</version>
<properties>
<maven.compiler.version>3.1</maven.compiler.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.dependency.version>3.1.1</maven.dependency.version>
</properties>
<repositories>
<repository>
<id>gitea</id>
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId>
<version>0.1.3</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test/src</testSourceDirectory>
<directory>${project.basedir}/out/maven/</directory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<!--<encoding>${project.build.sourceEncoding}</encoding>-->
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<mainClass>io.scenarium.oauth.WebLauncher</mainClass>
</configuration>
</plugin>
<!-- Create the source bundle -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- junit results -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<!-- Create coverage -->
<!--
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
-->
<!-- Java-doc generation for stand-alone site -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<show>private</show>
<nohelp>true</nohelp>
</configuration>
</plugin>
<!-- Check the style of the code -->
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<configLocation>CheckStyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
<failOnViolation>true</failOnViolation>
<failsOnError>true</failsOnError>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
</plugin>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>2.12.2</version>
<configuration>
<encoding>UTF-8</encoding>
<lineEnding>LF</lineEnding>
<configFile>Formatter.xml</configFile>
<directories>
<directory>src/</directory>
<directory>test/src</directory>
</directories>
<includes>
<include>**/*.java</include>
</includes>
<excludes>
<exclude>module-info.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
</plugin>
-->
</plugins>
</build>
<!-- Generate Java-docs As Part Of Project Reports -->
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<show>public</show>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -2,23 +2,11 @@ package org.kar.karusic;
import java.net.URI; import java.net.URI;
import jakarta.ws.rs.core.UriBuilder;
import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ResourceConfig;
import org.kar.karusic.api.AlbumResource;
import org.kar.karusic.api.ArtistResource;
import org.kar.karusic.api.Front;
import org.kar.karusic.api.GenderResource;
import org.kar.karusic.api.HealthCheck;
import org.kar.karusic.api.PlaylistResource;
import org.kar.karusic.api.TrackResource;
import org.kar.karusic.api.UserResource;
import org.kar.karusic.filter.KarusicAuthenticationFilter;
import org.kar.karusic.migration.Initialization;
import org.kar.archidata.GlobalConfiguration; import org.kar.archidata.GlobalConfiguration;
import org.kar.archidata.UpdateJwtPublicKey; import org.kar.archidata.UpdateJwtPublicKey;
import org.kar.archidata.api.DataResource; import org.kar.archidata.api.DataResource;
@ -30,23 +18,37 @@ import org.kar.archidata.filter.CORSFilter;
import org.kar.archidata.filter.OptionFilter; import org.kar.archidata.filter.OptionFilter;
import org.kar.archidata.migration.MigrationEngine; import org.kar.archidata.migration.MigrationEngine;
import org.kar.archidata.util.ConfigBaseVariable; import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.LoggerFactory; import org.kar.karusic.api.AlbumResource;
import org.kar.karusic.api.ArtistResource;
import org.kar.karusic.api.Front;
import org.kar.karusic.api.GenderResource;
import org.kar.karusic.api.HealthCheck;
import org.kar.karusic.api.PlaylistResource;
import org.kar.karusic.api.TrackResource;
import org.kar.karusic.api.UserResource;
import org.kar.karusic.filter.KarusicAuthenticationFilter;
import org.kar.karusic.migration.Initialization;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.UriBuilder;
public class WebLauncher { public class WebLauncher {
final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class); final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
protected UpdateJwtPublicKey keyUpdater = null; protected UpdateJwtPublicKey keyUpdater = null;
protected HttpServer server = null;
public WebLauncher() { public WebLauncher() {
ConfigBaseVariable.bdDatabase = "karusic"; ConfigBaseVariable.bdDatabase = "karusic";
} }
private static URI getBaseURI() { private static URI getBaseURI() {
return UriBuilder.fromUri(ConfigBaseVariable.getlocalAddress()).build(); return UriBuilder.fromUri(ConfigBaseVariable.getlocalAddress()).build();
} }
public void migrateDB() throws Exception { public void migrateDB() throws Exception {
WebLauncher.LOGGER.info("Create migration engine"); WebLauncher.LOGGER.info("Create migration engine");
MigrationEngine migrationEngine = new MigrationEngine(); final MigrationEngine migrationEngine = new MigrationEngine();
WebLauncher.LOGGER.info("Add initialization"); WebLauncher.LOGGER.info("Add initialization");
migrationEngine.setInit(new Initialization()); migrationEngine.setInit(new Initialization());
WebLauncher.LOGGER.info("Add migration since last version"); WebLauncher.LOGGER.info("Add migration since last version");
@ -56,9 +58,9 @@ public class WebLauncher {
WebLauncher.LOGGER.info("Migrate the DB [STOP]"); WebLauncher.LOGGER.info("Migrate the DB [STOP]");
} }
public static void main(String[] args) throws Exception { public static void main(final String[] args) throws Exception {
WebLauncher.LOGGER.info("[START] application wake UP"); WebLauncher.LOGGER.info("[START] application wake UP");
WebLauncher launcher = new WebLauncher(); final WebLauncher launcher = new WebLauncher();
launcher.migrateDB(); launcher.migrateDB();
launcher.process(); launcher.process();
@ -68,43 +70,42 @@ public class WebLauncher {
launcher.stopOther(); launcher.stopOther();
WebLauncher.LOGGER.info("STOP the REST server:"); WebLauncher.LOGGER.info("STOP the REST server:");
} }
public void process() throws InterruptedException { public void process() throws InterruptedException {
// =================================================================== // ===================================================================
// Configure resources // Configure resources
// =================================================================== // ===================================================================
ResourceConfig rc = new ResourceConfig(); final ResourceConfig rc = new ResourceConfig();
// add multipart models .. // add multipart models ..
rc.register(MultiPartFeature.class); rc.register(MultiPartFeature.class);
// global authentication system // global authentication system
rc.register(OptionFilter.class); rc.register(OptionFilter.class);
// remove cors ==> all time called by an other system... // remove cors ==> all time called by an other system...
rc.register(CORSFilter.class); rc.register(CORSFilter.class);
// global authentication system // global authentication system
rc.register(KarusicAuthenticationFilter.class); rc.register(KarusicAuthenticationFilter.class);
// register exception catcher // register exception catcher
rc.register(InputExceptionCatcher.class); rc.register(InputExceptionCatcher.class);
rc.register(SystemExceptionCatcher.class); rc.register(SystemExceptionCatcher.class);
rc.register(FailExceptionCatcher.class); rc.register(FailExceptionCatcher.class);
rc.register(ExceptionCatcher.class); rc.register(ExceptionCatcher.class);
// add default resource: // add default resource:
rc.register(UserResource.class); rc.register(UserResource.class);
rc.register(AlbumResource.class); rc.register(AlbumResource.class);
rc.register(ArtistResource.class); rc.register(ArtistResource.class);
rc.register(GenderResource.class); rc.register(GenderResource.class);
rc.register(PlaylistResource.class); rc.register(PlaylistResource.class);
rc.register(TrackResource.class); rc.register(TrackResource.class);
rc.register(DataResource.class); rc.register(DataResource.class);
rc.register(HealthCheck.class); rc.register(HealthCheck.class);
rc.register(Front.class); rc.register(Front.class);
// add jackson to be discover when we are ins standalone server // add jackson to be discover when we are ins standalone server
rc.register(JacksonFeature.class); rc.register(JacksonFeature.class);
// enable this to show low level request // enable this to show low level request
//rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName()); //rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
//System.out.println("Connect on the BDD:"); //System.out.println("Connect on the BDD:");
//System.out.println(" getDBHost: '" + ConfigVariable.getDBHost() + "'"); //System.out.println(" getDBHost: '" + ConfigVariable.getDBHost() + "'");
@ -114,12 +115,13 @@ public class WebLauncher {
//System.out.println(" getDBName: '" + ConfigVariable.getDBName() + "'"); //System.out.println(" getDBName: '" + ConfigVariable.getDBName() + "'");
System.out.println(" ==> " + GlobalConfiguration.dbConfig); System.out.println(" ==> " + GlobalConfiguration.dbConfig);
System.out.println("OAuth service " + getBaseURI()); System.out.println("OAuth service " + getBaseURI());
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc); this.server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
final HttpServer serverLink = this.server;
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
System.out.println("Stopping server.."); System.out.println("Stopping server..");
server.shutdownNow(); serverLink.shutdownNow();
} }
}, "shutdownHook")); }, "shutdownHook"));
@ -129,25 +131,32 @@ public class WebLauncher {
this.keyUpdater = new UpdateJwtPublicKey(); this.keyUpdater = new UpdateJwtPublicKey();
this.keyUpdater.start(); this.keyUpdater.start();
// =================================================================== // ===================================================================
// run JERSEY // run JERSEY
// =================================================================== // ===================================================================
try { try {
server.start(); this.server.start();
LOGGER.info("Jersey app started at {}", getBaseURI()); LOGGER.info("Jersey app started at {}", getBaseURI());
} catch (Exception e) { } catch (final Exception e) {
LOGGER.error("There was an error while starting Grizzly HTTP server."); LOGGER.error("There was an error while starting Grizzly HTTP server.");
e.printStackTrace(); e.printStackTrace();
} }
} }
public void stopOther() { public void stop() {
keyUpdater.kill(); if (this.server != null) {
this.server.shutdownNow();
this.server = null;
}
}
public void stopOther() {
this.keyUpdater.kill();
try { try {
keyUpdater.join(4000, 0); this.keyUpdater.join(4000, 0);
} catch (InterruptedException e) { } catch (final InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@ -5,12 +5,12 @@ import java.util.List;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam; import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany;
import org.kar.archidata.util.DataTools; import org.kar.archidata.util.DataTools;
import org.kar.karusic.model.Album; import org.kar.karusic.model.Album;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE; import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
@ -25,75 +25,75 @@ import jakarta.ws.rs.core.Response;
@Path("/album") @Path("/album")
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public class AlbumResource { public class AlbumResource {
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("USER") @RolesAllowed("USER")
public static Album getWithId(@PathParam("id") Long id) throws Exception { public static Album getWithId(@PathParam("id") final Long id) throws Exception {
return SqlWrapper.get(Album.class, id); return DataAccess.get(Album.class, id);
} }
@GET @GET
@RolesAllowed("USER") @RolesAllowed("USER")
public List<Album> get() throws Exception { public List<Album> get() throws Exception {
return SqlWrapper.gets(Album.class); return DataAccess.gets(Album.class);
} }
@POST @POST
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Album post(String jsonRequest) throws Exception { public Album post(final String jsonRequest) throws Exception {
return SqlWrapper.insertWithJson(Album.class, jsonRequest); return DataAccess.insertWithJson(Album.class, jsonRequest);
} }
@PUT @PUT
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Album put(@PathParam("id") Long id, String jsonRequest) throws Exception { public Album put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
SqlWrapper.update(Album.class, id, jsonRequest); DataAccess.updateWithJson(Album.class, id, jsonRequest);
return SqlWrapper.get(Album.class, id); return DataAccess.get(Album.class, id);
} }
@DELETE @DELETE
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response delete(@PathParam("id") Long id) throws Exception { public Response delete(@PathParam("id") final Long id) throws Exception {
SqlWrapper.delete(Album.class, id); DataAccess.delete(Album.class, id);
return Response.ok().build(); return Response.ok().build();
} }
@POST @POST
@Path("{id}/add_track/{trackId}") @Path("{id}/add_track/{trackId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Album addTrack(@PathParam("id") Long id, @PathParam("trackId") Long trackId) throws Exception { public Album addTrack(@PathParam("id") final Long id, @PathParam("trackId") final Long trackId) throws Exception {
AddOnManyToMany.removeLink(Album.class, id, "track", trackId); AddOnManyToMany.removeLink(Album.class, id, "track", trackId);
return SqlWrapper.get(Album.class, id); return DataAccess.get(Album.class, id);
} }
@GET @GET
@Path("{id}/rm_track/{trackId}") @Path("{id}/rm_track/{trackId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Album removeTrack(@PathParam("id") Long id, @PathParam("trackId") Long trackId) throws Exception { public Album removeTrack(@PathParam("id") final Long id, @PathParam("trackId") final Long trackId) throws Exception {
AddOnManyToMany.removeLink(Album.class, id, "track", trackId); AddOnManyToMany.removeLink(Album.class, id, "track", trackId);
return SqlWrapper.get(Album.class, id); return DataAccess.get(Album.class, id);
} }
@POST @POST
@Path("{id}/add_cover") @Path("{id}/add_cover")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Response uploadCover(@PathParam("id") Long id, @FormDataParam("fileName") String fileName, @FormDataParam("file") InputStream fileInputStream, public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData) { @FormDataParam("file") final FormDataContentDisposition fileMetaData) {
return DataTools.uploadCover(Album.class, id, fileName, fileInputStream, fileMetaData); return DataTools.uploadCover(Album.class, id, fileName, fileInputStream, fileMetaData);
} }
@GET @GET
@Path("{id}/rm_cover/{coverId}") @Path("{id}/rm_cover/{coverId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response removeCover(@PathParam("id") Long id, @PathParam("coverId") Long coverId) throws Exception { public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
AddOnManyToMany.removeLink(Album.class, id, "cover", coverId); AddOnManyToMany.removeLink(Album.class, id, "cover", coverId);
return Response.ok(SqlWrapper.get(Album.class, id)).build(); return Response.ok(DataAccess.get(Album.class, id)).build();
} }
} }

View File

@ -5,12 +5,12 @@ import java.util.List;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam; import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany;
import org.kar.archidata.util.DataTools; import org.kar.archidata.util.DataTools;
import org.kar.karusic.model.Artist; import org.kar.karusic.model.Artist;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE; import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
@ -25,58 +25,58 @@ import jakarta.ws.rs.core.Response;
@Path("/artist") @Path("/artist")
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public class ArtistResource { public class ArtistResource {
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("USER") @RolesAllowed("USER")
public static Artist getWithId(@PathParam("id") Long id) throws Exception { public static Artist getWithId(@PathParam("id") final Long id) throws Exception {
return SqlWrapper.get(Artist.class, id); return DataAccess.get(Artist.class, id);
} }
@GET @GET
@RolesAllowed("USER") @RolesAllowed("USER")
public List<Artist> get() throws Exception { public List<Artist> get() throws Exception {
return SqlWrapper.gets(Artist.class); return DataAccess.gets(Artist.class);
} }
@POST @POST
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Artist put(String jsonRequest) throws Exception { public Artist put(final String jsonRequest) throws Exception {
return SqlWrapper.insertWithJson(Artist.class, jsonRequest); return DataAccess.insertWithJson(Artist.class, jsonRequest);
} }
@PUT @PUT
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Artist put(@PathParam("id") Long id, String jsonRequest) throws Exception { public Artist put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
SqlWrapper.update(Artist.class, id, jsonRequest); DataAccess.updateWithJson(Artist.class, id, jsonRequest);
return SqlWrapper.get(Artist.class, id); return DataAccess.get(Artist.class, id);
} }
@DELETE @DELETE
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response delete(@PathParam("id") Long id) throws Exception { public Response delete(@PathParam("id") final Long id) throws Exception {
SqlWrapper.delete(Artist.class, id); DataAccess.delete(Artist.class, id);
return Response.ok().build(); return Response.ok().build();
} }
@POST @POST
@Path("{id}/add_cover") @Path("{id}/add_cover")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Response uploadCover(@PathParam("id") Long id, @FormDataParam("fileName") String fileName, @FormDataParam("file") InputStream fileInputStream, public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData) { @FormDataParam("file") final FormDataContentDisposition fileMetaData) {
return DataTools.uploadCover(Artist.class, id, fileName, fileInputStream, fileMetaData); return DataTools.uploadCover(Artist.class, id, fileName, fileInputStream, fileMetaData);
} }
@GET @GET
@Path("{id}/rm_cover/{coverId}") @Path("{id}/rm_cover/{coverId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response removeCover(@PathParam("id") Long id, @PathParam("coverId") Long coverId) throws Exception { public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
AddOnManyToMany.removeLink(Artist.class, id, "cover", coverId); AddOnManyToMany.removeLink(Artist.class, id, "cover", coverId);
return Response.ok(SqlWrapper.get(Artist.class, id)).build(); return Response.ok(DataAccess.get(Artist.class, id)).build();
} }
} }

View File

@ -1,22 +1,14 @@
package org.kar.karusic.api; package org.kar.karusic.api;
import java.io.File;
import java.util.List;
import org.kar.archidata.annotation.security.PermitAll;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.CacheControl;
import jakarta.ws.rs.core.PathSegment;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder;
import org.kar.archidata.api.FrontGeneric; import org.kar.archidata.api.FrontGeneric;
import org.kar.karusic.util.ConfigVariable; import org.kar.karusic.util.ConfigVariable;
import jakarta.ws.rs.Path;
@Path("/front") @Path("/front")
public class Front extends FrontGeneric { public class Front extends FrontGeneric {
public Front() { public Front() {
this.baseFrontFolder = ConfigVariable.getFrontFolder(); this.baseFrontFolder = ConfigVariable.getFrontFolder();
} }
} }

View File

@ -5,12 +5,12 @@ import java.util.List;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam; import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany;
import org.kar.archidata.util.DataTools; import org.kar.archidata.util.DataTools;
import org.kar.karusic.model.Gender; import org.kar.karusic.model.Gender;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE; import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
@ -25,58 +25,58 @@ import jakarta.ws.rs.core.Response;
@Path("/gender") @Path("/gender")
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public class GenderResource { public class GenderResource {
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("USER") @RolesAllowed("USER")
public static Gender getWithId(@PathParam("id") Long id) throws Exception { public static Gender getWithId(@PathParam("id") final Long id) throws Exception {
return SqlWrapper.get(Gender.class, id); return DataAccess.get(Gender.class, id);
} }
@GET @GET
@RolesAllowed("USER") @RolesAllowed("USER")
public List<Gender> get() throws Exception { public List<Gender> get() throws Exception {
return SqlWrapper.gets(Gender.class); return DataAccess.gets(Gender.class);
} }
@POST @POST
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Gender put(String jsonRequest) throws Exception { public Gender put(final String jsonRequest) throws Exception {
return SqlWrapper.insertWithJson(Gender.class, jsonRequest); return DataAccess.insertWithJson(Gender.class, jsonRequest);
} }
@PUT @PUT
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Gender put(@PathParam("id") Long id, String jsonRequest) throws Exception { public Gender put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
SqlWrapper.update(Gender.class, id, jsonRequest); DataAccess.updateWithJson(Gender.class, id, jsonRequest);
return SqlWrapper.get(Gender.class, id); return DataAccess.get(Gender.class, id);
} }
@DELETE @DELETE
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response delete(@PathParam("id") Long id) throws Exception { public Response delete(@PathParam("id") final Long id) throws Exception {
SqlWrapper.delete(Gender.class, id); DataAccess.delete(Gender.class, id);
return Response.ok().build(); return Response.ok().build();
} }
@POST @POST
@Path("{id}/add_cover") @Path("{id}/add_cover")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Response uploadCover(@PathParam("id") Long id, @FormDataParam("fileName") String fileName, @FormDataParam("file") InputStream fileInputStream, public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData) { @FormDataParam("file") final FormDataContentDisposition fileMetaData) {
return DataTools.uploadCover(Gender.class, id, fileName, fileInputStream, fileMetaData); return DataTools.uploadCover(Gender.class, id, fileName, fileInputStream, fileMetaData);
} }
@GET @GET
@Path("{id}/rm_cover/{coverId}") @Path("{id}/rm_cover/{coverId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response removeCover(@PathParam("id") Long id, @PathParam("coverId") Long coverId) throws Exception { public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
AddOnManyToMany.removeLink(Gender.class, id, "cover", coverId); AddOnManyToMany.removeLink(Gender.class, id, "cover", coverId);
return Response.ok(SqlWrapper.get(Gender.class, id)).build(); return Response.ok(DataAccess.get(Gender.class, id)).build();
} }
} }

View File

@ -1,28 +1,29 @@
package org.kar.karusic.api; package org.kar.karusic.api;
import org.kar.archidata.annotation.security.PermitAll; import org.kar.archidata.exception.FailException;
import jakarta.ws.rs.core.Response; import org.kar.archidata.util.ConfigBaseVariable;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import org.kar.archidata.util.JWTWrapper; import org.kar.archidata.util.JWTWrapper;
import jakarta.annotation.security.PermitAll;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@Path("/health_check") @Path("/health_check")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public class HealthCheck { public class HealthCheck {
public class HealthResult {
public String value; public record HealthResult(
public HealthResult(String value) { String value) {};
this.value = value;
@GET
@PermitAll
public HealthResult getHealth() throws FailException {
if (JWTWrapper.getPublicKeyJson() == null && !ConfigBaseVariable.getTestMode()) {
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Missing Jwt public token");
} }
return new HealthResult("alive and kicking");
} }
// todo : do it better...
@GET
@PermitAll
public Response getHealth() {
if (JWTWrapper.getPublicKeyJson() == null) {
return Response.status(500).entity(new HealthResult("Missing Jwt public token")).build();
}
return Response.status(200).entity(new HealthResult("alive and kicking")).build();
}
} }

View File

@ -5,12 +5,12 @@ import java.util.List;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam; import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany;
import org.kar.archidata.util.DataTools; import org.kar.archidata.util.DataTools;
import org.kar.karusic.model.Playlist; import org.kar.karusic.model.Playlist;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE; import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
@ -25,75 +25,75 @@ import jakarta.ws.rs.core.Response;
@Path("/playlist") @Path("/playlist")
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public class PlaylistResource { public class PlaylistResource {
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("USER") @RolesAllowed("USER")
public static Playlist getWithId(@PathParam("id") Long id) throws Exception { public static Playlist getWithId(@PathParam("id") final Long id) throws Exception {
return SqlWrapper.get(Playlist.class, id); return DataAccess.get(Playlist.class, id);
} }
@GET @GET
@RolesAllowed("USER") @RolesAllowed("USER")
public List<Playlist> get() throws Exception { public List<Playlist> get() throws Exception {
return SqlWrapper.gets(Playlist.class); return DataAccess.gets(Playlist.class);
} }
@POST @POST
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Playlist put(String jsonRequest) throws Exception { public Playlist put(final String jsonRequest) throws Exception {
return SqlWrapper.insertWithJson(Playlist.class, jsonRequest); return DataAccess.insertWithJson(Playlist.class, jsonRequest);
} }
@PUT @PUT
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Playlist put(@PathParam("id") Long id, String jsonRequest) throws Exception { public Playlist put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
SqlWrapper.update(Playlist.class, id, jsonRequest); DataAccess.updateWithJson(Playlist.class, id, jsonRequest);
return SqlWrapper.get(Playlist.class, id); return DataAccess.get(Playlist.class, id);
} }
@DELETE @DELETE
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response delete(@PathParam("id") Long id) throws Exception { public Response delete(@PathParam("id") final Long id) throws Exception {
SqlWrapper.delete(Playlist.class, id); DataAccess.delete(Playlist.class, id);
return Response.ok().build(); return Response.ok().build();
} }
@POST @POST
@Path("{id}/add_track/{trackId}") @Path("{id}/add_track/{trackId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Playlist addTrack(@PathParam("id") Long id, @PathParam("trackId") Long trackId) throws Exception { public Playlist addTrack(@PathParam("id") final Long id, @PathParam("trackId") final Long trackId) throws Exception {
AddOnManyToMany.removeLink(Playlist.class, id, "track", trackId); AddOnManyToMany.removeLink(Playlist.class, id, "track", trackId);
return SqlWrapper.get(Playlist.class, id); return DataAccess.get(Playlist.class, id);
} }
@GET @GET
@Path("{id}/rm_track/{trackId}") @Path("{id}/rm_track/{trackId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Playlist removeTrack(@PathParam("id") Long id, @PathParam("trackId") Long trackId) throws Exception { public Playlist removeTrack(@PathParam("id") final Long id, @PathParam("trackId") final Long trackId) throws Exception {
AddOnManyToMany.removeLink(Playlist.class, id, "track", trackId); AddOnManyToMany.removeLink(Playlist.class, id, "track", trackId);
return SqlWrapper.get(Playlist.class, id); return DataAccess.get(Playlist.class, id);
} }
@POST @POST
@Path("{id}/add_cover") @Path("{id}/add_cover")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Response uploadCover(@PathParam("id") Long id, @FormDataParam("fileName") String fileName, @FormDataParam("file") InputStream fileInputStream, public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData) { @FormDataParam("file") final FormDataContentDisposition fileMetaData) {
return DataTools.uploadCover(Playlist.class, id, fileName, fileInputStream, fileMetaData); return DataTools.uploadCover(Playlist.class, id, fileName, fileInputStream, fileMetaData);
} }
@GET @GET
@Path("{id}/rm_cover/{coverId}") @Path("{id}/rm_cover/{coverId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response removeCover(@PathParam("id") Long id, @PathParam("coverId") Long coverId) throws Exception { public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
AddOnManyToMany.removeLink(Playlist.class, id, "cover", coverId); AddOnManyToMany.removeLink(Playlist.class, id, "cover", coverId);
return Response.ok(SqlWrapper.get(Playlist.class, id)).build(); return Response.ok(DataAccess.get(Playlist.class, id)).build();
} }
} }

View File

@ -8,17 +8,17 @@ import java.util.List;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam; import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
import org.kar.archidata.model.Data; import org.kar.archidata.model.Data;
import org.kar.archidata.sqlWrapper.QuerryCondition;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany;
import org.kar.archidata.util.DataTools; import org.kar.archidata.util.DataTools;
import org.kar.karusic.model.Album; import org.kar.karusic.model.Album;
import org.kar.karusic.model.Artist; import org.kar.karusic.model.Artist;
import org.kar.karusic.model.Gender; import org.kar.karusic.model.Gender;
import org.kar.karusic.model.Track; import org.kar.karusic.model.Track;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE; import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
@ -37,37 +37,37 @@ public class TrackResource {
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("USER") @RolesAllowed("USER")
public static Track getWithId(@PathParam("id") Long id) throws Exception { public static Track getWithId(@PathParam("id") final Long id) throws Exception {
return SqlWrapper.get(Track.class, id); return DataAccess.get(Track.class, id);
} }
@GET @GET
@RolesAllowed("USER") @RolesAllowed("USER")
public List<Track> get() throws Exception { public List<Track> get() throws Exception {
return SqlWrapper.gets(Track.class); return DataAccess.gets(Track.class);
} }
@POST @POST
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Track create(String jsonRequest) throws Exception { public Track create(final String jsonRequest) throws Exception {
return SqlWrapper.insertWithJson(Track.class, jsonRequest); return DataAccess.insertWithJson(Track.class, jsonRequest);
} }
@PUT @PUT
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Track put(@PathParam("id") Long id, String jsonRequest) throws Exception { public Track put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
SqlWrapper.update(Track.class, id, jsonRequest); DataAccess.updateWithJson(Track.class, id, jsonRequest);
return SqlWrapper.get(Track.class, id); return DataAccess.get(Track.class, id);
} }
@DELETE @DELETE
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response delete(@PathParam("id") Long id) throws Exception { public Response delete(@PathParam("id") final Long id) throws Exception {
SqlWrapper.delete(Track.class, id); DataAccess.delete(Track.class, id);
return Response.ok().build(); return Response.ok().build();
} }
@ -75,34 +75,34 @@ public class TrackResource {
@Path("{id}/add_artist/{artistId}") @Path("{id}/add_artist/{artistId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Track addTrack(@PathParam("id") Long id, @PathParam("artistId") Long artistId) throws Exception { public Track addTrack(@PathParam("id") final Long id, @PathParam("artistId") final Long artistId) throws Exception {
AddOnManyToMany.removeLink(Track.class, id, "artist", artistId); AddOnManyToMany.removeLink(Track.class, id, "artist", artistId);
return SqlWrapper.get(Track.class, id); return DataAccess.get(Track.class, id);
} }
@GET @GET
@Path("{id}/rm_artist/{trackId}") @Path("{id}/rm_artist/{trackId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Track removeTrack(@PathParam("id") Long id, @PathParam("artistId") Long artistId) throws Exception { public Track removeTrack(@PathParam("id") final Long id, @PathParam("artistId") final Long artistId) throws Exception {
AddOnManyToMany.removeLink(Track.class, id, "artist", artistId); AddOnManyToMany.removeLink(Track.class, id, "artist", artistId);
return SqlWrapper.get(Track.class, id); return DataAccess.get(Track.class, id);
} }
@POST @POST
@Path("{id}/add_cover") @Path("{id}/add_cover")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Response uploadCover(@PathParam("id") Long id, @FormDataParam("fileName") String fileName, @FormDataParam("file") InputStream fileInputStream, public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData) { @FormDataParam("file") final FormDataContentDisposition fileMetaData) {
return DataTools.uploadCover(Track.class, id, fileName, fileInputStream, fileMetaData); return DataTools.uploadCover(Track.class, id, fileName, fileInputStream, fileMetaData);
} }
@GET @GET
@Path("{id}/rm_cover/{coverId}") @Path("{id}/rm_cover/{coverId}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response removeCover(@PathParam("id") Long id, @PathParam("coverId") Long coverId) throws Exception { public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
AddOnManyToMany.removeLink(Track.class, id, "cover", coverId); AddOnManyToMany.removeLink(Track.class, id, "cover", coverId);
return Response.ok(SqlWrapper.get(Track.class, id)).build(); return Response.ok(DataAccess.get(Track.class, id)).build();
} }
@POST @POST
@ -111,8 +111,8 @@ public class TrackResource {
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
public Response uploadFile(@FormDataParam("fileName") String fileName, @FormDataParam("gender") String gender, @FormDataParam("artist") String artist, public Response uploadFile(@FormDataParam("fileName") String fileName, @FormDataParam("gender") String gender, @FormDataParam("artist") String artist,
//@FormDataParam("seriesId") String seriesId, Not used ... //@FormDataParam("seriesId") String seriesId, Not used ...
@FormDataParam("album") String album, @FormDataParam("trackId") String trackId, @FormDataParam("title") String title, @FormDataParam("file") InputStream fileInputStream, @FormDataParam("album") String album, @FormDataParam("trackId") String trackId, @FormDataParam("title") String title, @FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData) { @FormDataParam("file") final FormDataContentDisposition fileMetaData) {
try { try {
// correct input string stream : // correct input string stream :
fileName = DataTools.multipartCorrection(fileName); fileName = DataTools.multipartCorrection(fileName);
@ -142,24 +142,24 @@ public class TrackResource {
} }
*/ */
long tmpUID = DataTools.getTmpDataId(); final long tmpUID = DataTools.getTmpDataId();
String sha512 = DataTools.saveTemporaryFile(fileInputStream, tmpUID); final String sha512 = DataTools.saveTemporaryFile(fileInputStream, tmpUID);
Data data = DataTools.getWithSha512(sha512); Data data = DataTools.getWithSha512(sha512);
if (data == null) { if (data == null) {
System.out.println("Need to add the data in the BDD ... "); System.out.println("Need to add the data in the BDD ... ");
System.out.flush(); System.out.flush();
try { try {
data = DataTools.createNewData(tmpUID, fileName, sha512); data = DataTools.createNewData(tmpUID, fileName, sha512);
} catch (IOException ex) { } catch (final IOException ex) {
DataTools.removeTemporaryFile(tmpUID); DataTools.removeTemporaryFile(tmpUID);
ex.printStackTrace(); ex.printStackTrace();
return Response.notModified("can not create input media").build(); return Response.notModified("can not create input media").build();
} catch (SQLException ex) { } catch (final SQLException ex) {
ex.printStackTrace(); ex.printStackTrace();
DataTools.removeTemporaryFile(tmpUID); DataTools.removeTemporaryFile(tmpUID);
return Response.notModified("Error in SQL insertion ...").build(); return Response.notModified("Error in SQL insertion ...").build();
} }
} else if (data.deleted == true) { } else if (data.deleted) {
System.out.println("Data already exist but deleted"); System.out.println("Data already exist but deleted");
System.out.flush(); System.out.flush();
DataTools.undelete(data.id); DataTools.undelete(data.id);
@ -172,11 +172,11 @@ public class TrackResource {
System.out.println("Find typeNode"); System.out.println("Find typeNode");
Gender genderElem = null; Gender genderElem = null;
if (gender != null) { if (gender != null) {
genderElem = SqlWrapper.getWhere(Gender.class, new QuerryCondition("name", "=", gender)); genderElem = DataAccess.getWhere(Gender.class, new QueryCondition("name", "=", gender));
if (genderElem == null) { if (genderElem == null) {
genderElem = new Gender(); genderElem = new Gender();
genderElem.name = gender; genderElem.name = gender;
genderElem = SqlWrapper.insert(genderElem); genderElem = DataAccess.insert(genderElem);
} }
} }
// NodeSmall typeNode = TypeResource.getWithId(Long.parseLong(typeId)); // NodeSmall typeNode = TypeResource.getWithId(Long.parseLong(typeId));
@ -188,22 +188,22 @@ public class TrackResource {
Artist artistElem = null; Artist artistElem = null;
if (artist != null) { if (artist != null) {
artistElem = SqlWrapper.getWhere(Artist.class, new QuerryCondition("name", "=", artist)); artistElem = DataAccess.getWhere(Artist.class, new QueryCondition("name", "=", artist));
if (artistElem == null) { if (artistElem == null) {
artistElem = new Artist(); artistElem = new Artist();
artistElem.name = artist; artistElem.name = artist;
artistElem = SqlWrapper.insert(artistElem); artistElem = DataAccess.insert(artistElem);
} }
} }
System.out.println(" ==> " + artistElem); System.out.println(" ==> " + artistElem);
Album albumElem = null; Album albumElem = null;
if (album != null) { if (album != null) {
albumElem = SqlWrapper.getWhere(Album.class, new QuerryCondition("name", "=", album)); albumElem = DataAccess.getWhere(Album.class, new QueryCondition("name", "=", album));
if (albumElem == null) { if (albumElem == null) {
albumElem = new Album(); albumElem = new Album();
albumElem.name = album; albumElem.name = album;
albumElem = SqlWrapper.insert(albumElem); albumElem = DataAccess.insert(albumElem);
} }
} }
System.out.println(" ==> " + album); System.out.println(" ==> " + album);
@ -221,15 +221,15 @@ public class TrackResource {
trackElem.artists = new ArrayList<>(); trackElem.artists = new ArrayList<>();
trackElem.artists.add(artistElem.id); trackElem.artists.add(artistElem.id);
} }
trackElem = SqlWrapper.insert(trackElem); trackElem = DataAccess.insert(trackElem);
/* /*
Old mode of artist insertion (removed due to the slowlest request of getting value Old mode of artist insertion (removed due to the slowlest request of getting value
if (artistElem != null) { if (artistElem != null) {
SqlWrapper.addLink(Track.class, trackElem.id, "artist", artistElem.id); DataAccess.addLink(Track.class, trackElem.id, "artist", artistElem.id);
} }
*/ */
return Response.ok(trackElem).build(); return Response.ok(trackElem).build();
} catch (Exception ex) { } catch (final Exception ex) {
System.out.println("Catch an unexpected error ... " + ex.getMessage()); System.out.println("Catch an unexpected error ... " + ex.getMessage());
ex.printStackTrace(); ex.printStackTrace();
return Response.status(417).entity("Back-end error : " + ex.getMessage()).type("text/plain").build(); return Response.status(417).entity("Back-end error : " + ex.getMessage()).type("text/plain").build();

View File

@ -2,15 +2,15 @@ package org.kar.karusic.api;
import java.util.List; import java.util.List;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.dataAccess.DataAccess;
import org.kar.archidata.filter.GenericContext; import org.kar.archidata.filter.GenericContext;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.karusic.model.UserKarusic; import org.kar.karusic.model.UserKarusic;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path; import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam; import jakarta.ws.rs.PathParam;
@ -29,14 +29,13 @@ public class UserResource {
public long id; public long id;
public String login; public String login;
public UserOut(long id, String login) { public UserOut(final long id, final String login) {
super();
this.id = id; this.id = id;
this.login = login; this.login = login;
} }
} }
public UserResource() {} public UserResource() {}
// curl http://localhost:9993/api/users // curl http://localhost:9993/api/users
@ -45,8 +44,8 @@ public class UserResource {
public List<UserKarusic> getUsers() { public List<UserKarusic> getUsers() {
System.out.println("getUsers"); System.out.println("getUsers");
try { try {
return SqlWrapper.gets(UserKarusic.class); return DataAccess.gets(UserKarusic.class);
} catch (Exception e) { } catch (final Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
@ -57,15 +56,15 @@ public class UserResource {
@GET @GET
@Path("{id}") @Path("{id}")
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public UserKarusic getUsers(@Context SecurityContext sc, @PathParam("id") long userId) { public UserKarusic getUsers(@Context final SecurityContext sc, @PathParam("id") final long userId) {
System.out.println("getUser " + userId); System.out.println("getUser " + userId);
GenericContext gc = (GenericContext) sc.getUserPrincipal(); final GenericContext gc = (GenericContext) sc.getUserPrincipal();
System.out.println("==================================================="); System.out.println("===================================================");
System.out.println("== USER ? " + gc.userByToken.name); System.out.println("== USER ? " + gc.userByToken.name);
System.out.println("==================================================="); System.out.println("===================================================");
try { try {
return SqlWrapper.get(UserKarusic.class, userId); return DataAccess.get(UserKarusic.class, userId);
} catch (Exception e) { } catch (final Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
@ -75,10 +74,10 @@ public class UserResource {
@GET @GET
@Path("me") @Path("me")
@RolesAllowed("USER") @RolesAllowed("USER")
public UserOut getMe(@Context SecurityContext sc) { public UserOut getMe(@Context final SecurityContext sc) {
logger.debug("getMe()"); this.logger.debug("getMe()");
GenericContext gc = (GenericContext) sc.getUserPrincipal(); final GenericContext gc = (GenericContext) sc.getUserPrincipal();
logger.debug("== USER ? {}", gc.userByToken); this.logger.debug("== USER ? {}", gc.userByToken);
return new UserOut(gc.userByToken.id, gc.userByToken.name); return new UserOut(gc.userByToken.id, gc.userByToken.name);
} }
} }

View File

@ -10,14 +10,14 @@ import org.kar.karusic.model.Playlist;
import org.kar.karusic.model.Track; import org.kar.karusic.model.Track;
public class Initialization extends MigrationSqlStep { public class Initialization extends MigrationSqlStep {
public static final int KARSO_INITIALISATION_ID = 1; public static final int KARSO_INITIALISATION_ID = 1;
@Override @Override
public String getName() { public String getName() {
return "Initialization"; return "Initialization";
} }
public Initialization() throws Exception { public Initialization() throws Exception {
addClass(Album.class); addClass(Album.class);
addClass(Artist.class); addClass(Artist.class);
@ -26,7 +26,7 @@ public class Initialization extends MigrationSqlStep {
addClass(Playlist.class); addClass(Playlist.class);
addClass(Track.class); addClass(Track.class);
addClass(User.class); addClass(User.class);
addAction(""" addAction("""
INSERT INTO `gender` (`id`, `name`, `description`) VALUES INSERT INTO `gender` (`id`, `name`, `description`) VALUES
(1, 'Variété française', NULL), (1, 'Variété française', NULL),
@ -59,25 +59,25 @@ public class Initialization extends MigrationSqlStep {
// set start increment element to permit to add after default elements // set start increment element to permit to add after default elements
addAction(""" addAction("""
ALTER TABLE `album` AUTO_INCREMENT = 1000; ALTER TABLE `album` AUTO_INCREMENT = 1000;
"""); """, "mysql");
addAction(""" addAction("""
ALTER TABLE `artist` AUTO_INCREMENT = 1000; ALTER TABLE `artist` AUTO_INCREMENT = 1000;
"""); """, "mysql");
addAction(""" addAction("""
ALTER TABLE `data` AUTO_INCREMENT = 1000; ALTER TABLE `data` AUTO_INCREMENT = 1000;
"""); """, "mysql");
addAction(""" addAction("""
ALTER TABLE `gender` AUTO_INCREMENT = 1000; ALTER TABLE `gender` AUTO_INCREMENT = 1000;
"""); """, "mysql");
addAction(""" addAction("""
ALTER TABLE `playlist` AUTO_INCREMENT = 1000; ALTER TABLE `playlist` AUTO_INCREMENT = 1000;
"""); """, "mysql");
addAction(""" addAction("""
ALTER TABLE `track` AUTO_INCREMENT = 1000; ALTER TABLE `track` AUTO_INCREMENT = 1000;
"""); """, "mysql");
addAction(""" addAction("""
ALTER TABLE `user` AUTO_INCREMENT = 1000; ALTER TABLE `user` AUTO_INCREMENT = 1000;
"""); """, "mysql");
} }
} }

View File

@ -14,14 +14,14 @@ CREATE TABLE `node` (
*/ */
import java.sql.Date; import java.sql.Date;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.DataIfNotExists;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@Table(name = "album") @Table(name = "album")
@SQLIfNotExists @DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Album extends NodeSmall { public class Album extends NodeSmall {
public Date publication = null; public Date publication = null;

View File

@ -14,7 +14,7 @@ CREATE TABLE `node` (
import java.sql.Date; import java.sql.Date;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.DataIfNotExists;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@ -22,7 +22,7 @@ import jakarta.persistence.Column;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@Table(name = "artist") @Table(name = "artist")
@SQLIfNotExists @DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Artist extends NodeSmall { public class Artist extends NodeSmall {
@Column(length = 256) @Column(length = 256)
@ -31,10 +31,10 @@ public class Artist extends NodeSmall {
public String surname = null; public String surname = null;
public Date birth = null; public Date birth = null;
public Date death = null; public Date death = null;
@Override @Override
public String toString() { public String toString() {
return "Artist [id=" + id + ", name=" + name + ", description=" + description + ", covers=" + covers + ", firstName=" + firstName + ", surname=" + surname + ", birth=" + birth + ", death=" return "Artist [id=" + this.id + ", name=" + this.name + ", description=" + this.description + ", covers=" + this.covers + ", firstName=" + this.firstName + ", surname=" + this.surname
+ death + "]"; + ", birth=" + this.birth + ", death=" + this.death + "]";
} }
} }

View File

@ -12,15 +12,15 @@ CREATE TABLE `node` (
) AUTO_INCREMENT=10; ) AUTO_INCREMENT=10;
*/ */
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.DataIfNotExists;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@Table(name = "gender") @Table(name = "gender")
@SQLIfNotExists @DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Gender extends NodeSmall { public class Gender extends NodeSmall {
} }

View File

@ -15,7 +15,7 @@ CREATE TABLE `node` (
import java.util.List; import java.util.List;
import org.kar.archidata.model.Data; import org.kar.archidata.model.Data;
import org.kar.archidata.model.GenericTable; import org.kar.archidata.model.GenericDataSoftDelete;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@ -24,7 +24,7 @@ import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToMany;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class NodeSmall extends GenericTable { public class NodeSmall extends GenericDataSoftDelete {
@Column(length = 256) @Column(length = 256)
public String name = null; public String name = null;
public String description = null; public String description = null;

View File

@ -14,7 +14,7 @@ CREATE TABLE `node` (
import java.util.List; import java.util.List;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.DataIfNotExists;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@ -23,7 +23,7 @@ import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@Table(name = "playlist") @Table(name = "playlist")
@SQLIfNotExists @DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Playlist extends NodeSmall { public class Playlist extends NodeSmall {
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Track.class) @ManyToMany(fetch = FetchType.LAZY, targetEntity = Track.class)

View File

@ -14,7 +14,7 @@ CREATE TABLE `node` (
import java.util.List; import java.util.List;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.DataIfNotExists;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@ -23,7 +23,7 @@ import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@Table(name = "track") @Table(name = "track")
@SQLIfNotExists @DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Track extends NodeSmall { public class Track extends NodeSmall {
public Long genderId = null; public Long genderId = null;
@ -32,10 +32,10 @@ public class Track extends NodeSmall {
public Long dataId = null; public Long dataId = null;
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Artist.class) @ManyToMany(fetch = FetchType.LAZY, targetEntity = Artist.class)
public List<Long> artists = null; public List<Long> artists = null;
@Override @Override
public String toString() { public String toString() {
return "Track [id=" + id + ", deleted=" + deleted + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + ", name=" + name + ", description=" + description + ", covers=" + covers return "Track [id=" + this.id + ", deleted=" + this.deleted + ", createdAt=" + this.createdAt + ", updatedAt=" + this.updatedAt + ", name=" + this.name + ", description=" + this.description
+ ", genderId=" + genderId + ", albumId=" + albumId + ", track=" + track + ", dataId=" + dataId + ", artists=" + artists + "]"; + ", covers=" + this.covers + ", genderId=" + this.genderId + ", albumId=" + this.albumId + ", track=" + this.track + ", dataId=" + this.dataId + ", artists=" + this.artists + "]";
} }
} }

View File

@ -1,6 +1,6 @@
package org.kar.karusic.model; package org.kar.karusic.model;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.model.User; import org.kar.archidata.model.User;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@ -8,8 +8,8 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@Table(name = "user") @Table(name = "user")
@SQLIfNotExists @DataIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class UserKarusic extends User { public class UserKarusic extends User {
} }

View File

@ -0,0 +1,35 @@
# SLF4J's SimpleLogger configuration file
# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
# Default logging detail level for all instances of SimpleLogger.
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, defaults to "info".
org.slf4j.simpleLogger.defaultLogLevel=debug
# Logging detail level for a SimpleLogger instance named "xxxxx".
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, the default logging detail level is used.
#org.slf4j.simpleLogger.log.xxxxx=
# Set to true if you want the current date and time to be included in output messages.
# Default is false, and will output the number of milliseconds elapsed since startup.
#org.slf4j.simpleLogger.showDateTime=false
# The date and time format to be used in the output messages.
# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
# If the format is not specified or is invalid, the default format is used.
# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
# Set to true if you want to output the current thread name.
# Defaults to true.
org.slf4j.simpleLogger.showThreadName=true
# Set to true if you want the Logger instance name to be included in output messages.
# Defaults to true.
#org.slf4j.simpleLogger.showLogName=true
# Set to true if you want the last component of the name to be included in output messages.
# Defaults to false.
#org.slf4j.simpleLogger.showShortLogName=false

View File

@ -0,0 +1,33 @@
package test.kar.karusic;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler {
@Override
public ConditionEvaluationResult evaluateExecutionCondition(final ExtensionContext extensionContext) {
final ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
final ExtensionContext.Store store = storeFor(extensionContext, namespace);
final String value = store.get(StepwiseExtension.class, String.class);
return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests")
: ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value));
}
@Override
public void handleTestExecutionException(final ExtensionContext extensionContext, final Throwable throwable) throws Throwable {
final ExtensionContext.Namespace namespace = namespaceFor(extensionContext);
final ExtensionContext.Store store = storeFor(extensionContext, namespace);
store.put(StepwiseExtension.class, extensionContext.getDisplayName());
throw throwable;
}
private ExtensionContext.Namespace namespaceFor(final ExtensionContext extensionContext) {
return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent());
}
private ExtensionContext.Store storeFor(final ExtensionContext extensionContext, final ExtensionContext.Namespace namespace) {
return extensionContext.getParent().get().getStore(namespace);
}
}

View File

@ -0,0 +1,250 @@
package test.kar.karusic;
import java.util.Map;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.kar.archidata.exception.RESTErrorResponseExeption;
import org.kar.archidata.model.GetToken;
import org.kar.archidata.util.ConfigBaseVariable;
import org.kar.archidata.util.JWTWrapper;
import org.kar.archidata.util.RESTApi;
import org.kar.karusic.api.HealthCheck.HealthResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
@ExtendWith(StepwiseExtension.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestBase {
private final static Logger LOGGER = LoggerFactory.getLogger(TestBase.class);
static WebLauncherTest webInterface = null;
static RESTApi api = null;
public void login(final String login, final String password) {
try {
final GetToken token = api.post(GetToken.class, "users/get_token", DataGetToken.generate(login, "v1", "202515252", password));
api.setToken(token.jwt());
} catch (final Exception ex) {
Assertions.fail("Can not get Authentication for '" + login + "' ==> " + ex.getMessage());
}
}
public void loginAdmin() {
login("karadmin", "adminA@666");
}
@BeforeAll
public static void configureWebServer() throws Exception {
LOGGER.info("configure server ...");
webInterface = new WebLauncherTest();
LOGGER.info("Create DB");
try {
webInterface.migrateDB();
} catch (final Exception ex) {
ex.printStackTrace();
LOGGER.error("Detect an error: {}", ex.getMessage());
}
LOGGER.info("Start REST (BEGIN)");
webInterface.process();
LOGGER.info("Start REST (DONE)");
api = new RESTApi(ConfigBaseVariable.apiAdress);
}
@AfterAll
public static void stopWebServer() throws InterruptedException {
LOGGER.info("Kill the web server");
webInterface = null;
// TODO: do it better...
}
@Order(1)
@Test
//@RepeatedTest(10)
public void checkHealthCheck() throws Exception {
final HealthResult result = api.get(HealthResult.class, "health_check");
Assertions.assertEquals(result.value(), "alive and kicking");
}
@Order(2)
@Test
public void checkHealthCheckWrongAPI() throws Exception {
Assertions.assertThrows(RESTErrorResponseExeption.class, () -> api.get(HealthResult.class, "health_checks"));
}
@Order(3)
@Test
public void firstUserConnect() throws Exception {
final GetToken result = api.post(GetToken.class, "users/get_token", DataGetToken.generate("karadmin", "v1", "202515252", "adminA@666"));
final String[] splitted = result.jwt().split("\\.");
Assertions.assertEquals(3, splitted.length);
final String authorization = result.jwt();
LOGGER.debug(" validate token : " + authorization);
// Note with local access we get the internal key of the system.
final JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
// check the token is valid !!! (signed and coherent issuer...
Assertions.assertNotNull(ret);
// check userID
final String userUID = ret.getSubject();
final long id = Long.parseLong(userUID);
Assertions.assertEquals(1, id);
final String name = (String) ret.getClaim("login");
Assertions.assertEquals("karadmin", name);
final Object rowRight = ret.getClaim("right");
Assertions.assertNotNull(rowRight);
final Map<String, Map<String, Object>> rights = (Map<String, Map<String, Object>>) ret.getClaim("right");
// Check if the element contain the basic keys:
Assertions.assertEquals(rights.size(), 1);
Assertions.assertTrue(rights.containsKey("karusic"));
final Map<String, Object> applRight = rights.get("karusic");
//logger.error("full right: {}", applRight);
Assertions.assertEquals(applRight.size(), 2);
Assertions.assertTrue(applRight.containsKey("ADMIN"));
Assertions.assertEquals(true, applRight.get("ADMIN"));
Assertions.assertTrue(applRight.containsKey("USER"));
Assertions.assertEquals(true, applRight.get("USER"));
//logger.debug("request user: '{}' right: '{}' row='{}'", userUID, applRight, rowRight);
//Assertions.assertEquals("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9", splitted[0]);
//Assertions.assertEquals("eyJzdWIiOiIwIiwiYXBwbGljYXRpb24iOiJrYXJzbyIsImlzcyI6IkthckF1dGgiLCJyaWdodCI6eyJrYXJzbyI6eyJBRE1JTiI6dHJ1ZSwiVVNFUiI6dHJ1ZX19LCJsb2dpbiI6ImthcmFkbWluIiwiZXhwIjoxNjg0MTk5MTkzLCJpYXQiOjE2ODI3NTU0MjV9", splitted[1]);
// TODO ... Assertions.assertEquals("????", splitted[2]);
}
public void checkFail(final String type, final String urlOffset, final int errorStatus) {
checkFail(type, urlOffset, errorStatus, null);
}
public void checkFail(final String type, final String urlOffset, final int errorStatus, final String data) {
LOGGER.info("Test API: url={} urlOffset={}", type, urlOffset);
try {
if ("GET".equals(type)) {
api.get(String.class, urlOffset);
} else if ("POST".equals(type)) {
api.post(String.class, urlOffset, data);
} else if ("PUT".equals(type)) {
api.put(String.class, urlOffset, data);
} else if ("DELETE".equals(type)) {
api.delete(String.class, urlOffset);
}
Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + urlOffset + "'");
} catch (final RESTErrorResponseExeption ex) {
if (errorStatus != ex.status) {
LOGGER.error("Fail in test with the wrong return errors: {}", ex.toString());
}
Assertions.assertEquals(errorStatus, ex.status);
} catch (final Exception ex) {
LOGGER.error("Unexpected throw error: {}", ex);
Assertions.fail("Unexpected throws...");
}
}
public void checkWork(final String type, final String urlOffset) {
checkWork(type, urlOffset, null);
}
public void checkWork(final String type, final String urlOffset, final String data) {
LOGGER.info("Test API: url={} urlOffset={}", type, urlOffset);
try {
if ("GET".equals(type)) {
api.get(String.class, urlOffset);
} else if ("POST".equals(type)) {
api.post(String.class, urlOffset, data);
} else if ("PUT".equals(type)) {
api.put(String.class, urlOffset, data);
} else if ("DELETE".equals(type)) {
api.delete(String.class, urlOffset);
}
//Assertions.fail("Request on URL does not fail as expected: '" + type + "' url='" + urlOffset + "'");
} catch (final RESTErrorResponseExeption ex) {
Assertions.fail("Must not fail ... " + ex.toString());
} catch (final Exception ex) {
LOGGER.error("Unexpected throw error: {}", ex);
Assertions.fail("Unexpected throws...");
}
}
@Order(4)
@Test
public void checkUnAuthorizedAPI() throws Exception {
// /application/
checkFail("GET", "application/", 401);
checkFail("POST", "application/", 401, "{}");
checkFail("PUT", "application/", 405, "{}"); // does not exist
checkFail("DELETE", "application/", 405); // does not exist
// /application/{id}
checkFail("GET", "application/0", 401);
checkFail("PUT", "application/0", 401, "{}");
checkFail("POST", "application/0", 405, "{}");
checkFail("DELETE", "application/0", 401);
// /application/{id}/*
checkFail("GET", "application/0/users", 401);
// /application/*
checkFail("GET", "application/small", 401);
checkFail("GET", "application/get_token", 401);
checkFail("GET", "application/return", 401);
// /application_token/ section:
checkFail("GET", "application_token/0", 401);
checkFail("DELETE", "application_token/0/5", 401);
checkFail("DELETE", "application_token/0/create", 401);
// /front/*
checkFail("GET", "front", 404); // no index in test section
// health check
checkWork("GET", "health_check");
// public_key (only application)
checkFail("GET", "public_key", 401);
checkFail("GET", "public_key/pem", 401);
// /right
checkFail("GET", "right", 401);
checkFail("POST", "right", 401, "{}");
checkFail("GET", "right/0", 401);
checkFail("PUT", "right/0", 401, "{}");
checkFail("DELETE", "right/0", 401);
// /system_config
checkWork("GET", "system_config/is_sign_up_availlable");
checkFail("GET", "system_config/key/skjdfhkjsdhfkjsh", 401);
checkFail("PUT", "system_config/key/skjdfhkjsdhfkjsh", 401, "{}");
// /users
checkFail("GET", "users", 401);
checkFail("GET", "users/0", 401);
checkFail("POST", "users/0/application/0/link", 401, "{}");
checkFail("POST", "users/0/set_admin", 401, "{}");
checkFail("POST", "users/0/set_blocked", 401, "{}");
checkFail("POST", "users/create_new_user", 401, "{}");
checkFail("GET", "users/me", 401, "{}");
checkFail("POST", "users/password", 401, "{}");
checkWork("GET", "users/check_login?login=karadmin");
checkFail("GET", "users/check_login?login=jhkjhkjh", 404);
checkWork("GET", "users/check_email?email=admin@admin.ZZZ");
checkFail("GET", "users/check_email?email=ksjhdkjfhskjdh", 404);
// not testable : get_token
}
@Order(5)
@Test
public void testMeWithToken() throws Exception {
loginAdmin();
final String result = api.get(String.class, "users/me");
Assertions.assertEquals("{\"id\":1,\"login\":\"karadmin\"}", result);
}
}

View File

@ -0,0 +1,28 @@
package test.kar.karusic;
import org.kar.archidata.util.ConfigBaseVariable;
import org.kar.karusic.WebLauncher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WebLauncherTest extends WebLauncher {
final private static Logger LOGGER = LoggerFactory.getLogger(WebLauncherTest.class);
public WebLauncherTest() {
LOGGER.debug("Configure REST system");
// for local test:
ConfigBaseVariable.apiAdress = "http://127.0.0.1:12345/test/api/";
ConfigBaseVariable.dbPort = "3306";
// for the test we a in memory sqlite..
ConfigBaseVariable.dbType = "sqlite";
ConfigBaseVariable.dbHost = "memory";
// for test we need to connect all time the DB
ConfigBaseVariable.dbKeepConnected = "true";
ConfigBaseVariable.dbHost = "localhost";
ConfigBaseVariable.dbUser = "root";
ConfigBaseVariable.dbPassword = "ZERTYSDGFVHSDFGHJYZSDFGSQxfgsqdfgsqdrf4564654";
}
}