[DEV] review many models and system

This commit is contained in:
Edouard DUPIN 2023-10-14 12:18:36 +02:00
parent 99cca8bebf
commit d8c6de7bde
79 changed files with 3367 additions and 2996 deletions

7
.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

@ -8,36 +8,20 @@
</classpathentry> </classpathentry>
<classpathentry kind="src" output="out/maven/test-classes" path="test/src"> <classpathentry kind="src" output="out/maven/test-classes" path="test/src">
<attributes> <attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/> <attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="out/maven/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" output="out/maven/test-classes" path="out/maven/generated-test-sources/test-annotations"> <classpathentry exported="true" kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes> <attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/> </attributes>
<attribute name="m2e-apt" value="true"/> </classpathentry>
<attribute name="test" value="true"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="output" path="out/maven/classes"/> <classpathentry kind="output" path="out/maven/classes"/>

1
conditioningUnit Normal file
View File

@ -0,0 +1 @@
[]

13
pom.xml
View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>kangaroo-and-rabbit</groupId> <groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId> <artifactId>archidata</artifactId>
<version>0.3.8</version> <version>0.4.0</version>
<properties> <properties>
<jersey.version>3.1.1</jersey.version> <jersey.version>3.1.1</jersey.version>
<jaxb.version>2.3.1</jaxb.version> <jaxb.version>2.3.1</jaxb.version>
@ -130,6 +130,17 @@
<artifactId>nimbus-jose-jwt</artifactId> <artifactId>nimbus-jose-jwt</artifactId>
<version>9.30</version> <version>9.30</version>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -16,3 +16,4 @@ public class GlobalConfiguration {
ConfigBaseVariable.getDBKeepConnected()); ConfigBaseVariable.getDBKeepConnected());
} }
} }

View File

@ -5,6 +5,7 @@ import org.kar.archidata.util.JWTWrapper;
public class UpdateJwtPublicKey extends Thread { public class UpdateJwtPublicKey extends Thread {
boolean kill = false; boolean kill = false;
public void run() { public void run() {
if (ConfigBaseVariable.getSSOAddress() == null) { if (ConfigBaseVariable.getSSOAddress() == null) {
System.out.println("SSO INTERFACE is not provided ==> work alone."); System.out.println("SSO INTERFACE is not provided ==> work alone.");
@ -28,6 +29,7 @@ public class UpdateJwtPublicKey extends Thread {
} }
} }
} }
public void kill() { public void kill() {
this.kill = true; this.kill = true;
} }

View File

@ -1,23 +1,21 @@
package org.kar.archidata; package org.kar.archidata;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.model.User;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import java.io.IOException; import java.io.IOException;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.model.User;
import org.kar.archidata.sqlWrapper.SqlWrapper;
public class UserDB { public class UserDB {
public UserDB() { public UserDB() {}
}
public static User getUsers(long userId) throws Exception { public static User getUsers(long userId) throws Exception {
return SqlWrapper.get(User.class, userId); return SqlWrapper.get(User.class, userId);
} }
public static User getUserOrCreate(long userId, String userLogin) throws Exception { public static User getUserOrCreate(long userId, String userLogin) throws Exception {
User user = getUsers(userId); User user = getUsers(userId);
if (user != null) { if (user != null) {

View File

@ -0,0 +1,129 @@
package org.kar.archidata.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Table;
public class AnnotationTools {
static final Logger LOGGER = LoggerFactory.getLogger(AnnotationTools.class);
public static String getTableName(final Class<?> element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Table.class);
if (annotation.length == 0) {
return null;
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @SQLTableName on " + element.getClass().getCanonicalName());
}
final String tmp = ((Table) annotation[0]).name();
if (tmp == null) {
return null;
}
return tmp;
}
public static String getComment(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLComment.class);
if (annotation.length == 0) {
return null;
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @SQLComment on " + element.getClass().getCanonicalName());
}
final String tmp = ((SQLComment) annotation[0]).value();
if (tmp == null) {
return null;
}
return tmp;
}
public static String getDefault(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLDefault.class);
if (annotation.length == 0) {
return null;
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @SQLDefault on " + element.getClass().getCanonicalName());
}
final String tmp = ((SQLDefault) annotation[0]).value();
if (tmp == null) {
return null;
}
return tmp;
}
public static Integer getLimitSize(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
if (annotation.length == 0) {
return null;
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @SQLLimitSize on " + element.getClass().getCanonicalName());
}
return ((Column) annotation[0]).length();
}
public static boolean isAnnotationGroup(final Field field, final Class<?> annotationType) {
try {
final Annotation[] anns = field.getAnnotations();
for (final Annotation ann : anns) {
if (ann.annotationType() == annotationType) {
return true;
}
}
for (final Annotation ann : anns) {
final Annotation[] anns2 = ann.annotationType().getDeclaredAnnotations();
for (final Annotation ann2 : anns2) {
if (ann2.annotationType() == annotationType) {
return true;
}
}
}
} catch (final Exception ex) {
LOGGER.error("Catch exception when try to get annotation...{}", ex.getLocalizedMessage());
return false;
}
return false;
}
public static boolean getNotNull(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
if (annotation.length == 0) {
return true;
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
}
return ((Column) annotation[0]).nullable();
}
public static boolean isPrimaryKey(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
if (annotation.length == 0) {
return true;
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
}
return ((Column) annotation[0]).unique();
}
public static GenerationType getStrategy(final Field element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(GeneratedValue.class);
if (annotation.length == 0) {
return null;
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
}
return ((GeneratedValue) annotation[0]).strategy();
}
}

View File

@ -7,6 +7,6 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SQLCreateTime { public @interface CreationTimestamp {
} }

View File

@ -5,8 +5,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
@Target(ElementType.FIELD) @Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SQLPrimaryKey { public @interface SQLAddOn {
} }

View File

@ -1,12 +0,0 @@
package org.kar.archidata.annotation;
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 SQLLimitSize {
int value();
}

View File

@ -1,14 +0,0 @@
package org.kar.archidata.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLTableName {
String value();
}

View File

@ -1,12 +0,0 @@
package org.kar.archidata.annotation;
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 SQLUpdateTime {
}

View File

@ -7,6 +7,6 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SQLAutoIncrement { public @interface UpdateTimestamp {
} }

View File

@ -1,12 +1,15 @@
package org.kar.archidata.annotation; package org.kar.archidata.annotation.addOn;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.kar.archidata.annotation.SQLAddOn;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SQLNotNull { @SQLAddOn
public @interface SQLTableExternalForeinKeyAsList {
} }

View File

@ -1,32 +1,28 @@
package org.kar.archidata.annotation; package org.kar.archidata.annotation.addOn;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.kar.archidata.annotation.SQLAddOn;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SQLTableLinkGeneric { @SQLAddOn
public @interface SQLTableExternalLink {
public static String AUTOMATIC = "__auto__"; public static String AUTOMATIC = "__auto__";
public enum ModelLink {
NONE,
INTERNAL, // The list is serialized in a string ',' separated
EXTERNAL // an external table is created and
};
// Permit to select the link mode.
ModelLink value() default ModelLink.EXTERNAL;
// If automatic table name, the table name is: parentTableName_externalTableName__link // If automatic table name, the table name is: parentTableName_externalTableName__link
String tableName() default AUTOMATIC; String tableName() default AUTOMATIC;
// If automatic table name, the name of the foreign table is manage with the variable name. // If automatic table name, the name of the foreign table is manage with the variable name.
String externalTableName() default AUTOMATIC; String externalTableName() default AUTOMATIC;
// If the external link have a field to filter with a specific value (name of the field) // If the external link have a field to filter with a specific value (name of the field)
String filterField() default AUTOMATIC; String filterField() default AUTOMATIC;
// If the external link have a field to filter with a specific value (value of the field) // If the external link have a field to filter with a specific value (value of the field)
String filterValue() default AUTOMATIC; String filterValue() default AUTOMATIC;
} }

View File

@ -1,15 +1,14 @@
package org.kar.archidata.annotation.security; package org.kar.archidata.annotation.security;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import jakarta.ws.rs.NameBinding; import jakarta.ws.rs.NameBinding;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@NameBinding @NameBinding
@Retention(RUNTIME) @Retention(RUNTIME)
@Target({ METHOD }) @Target({ METHOD })
public @interface DenyAll { public @interface DenyAll {}
}

View File

@ -1,14 +1,14 @@
package org.kar.archidata.annotation.security; package org.kar.archidata.annotation.security;
import jakarta.ws.rs.NameBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import jakarta.ws.rs.NameBinding;
@NameBinding @NameBinding
@Retention(RUNTIME) @Retention(RUNTIME)
@Target({ METHOD }) @Target({ METHOD })
public @interface PermitAll { public @interface PermitAll {}
}

View File

@ -1,14 +1,14 @@
package org.kar.archidata.annotation.security; package org.kar.archidata.annotation.security;
import jakarta.ws.rs.NameBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import jakarta.ws.rs.NameBinding;
@NameBinding @NameBinding
@Retention(RUNTIME) @Retention(RUNTIME)
@Target({ METHOD }) @Target({ METHOD })
public @interface PermitTokenInURI { public @interface PermitTokenInURI {}
}

View File

@ -1,12 +1,13 @@
package org.kar.archidata.annotation.security; package org.kar.archidata.annotation.security;
import jakarta.ws.rs.NameBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import jakarta.ws.rs.NameBinding;
@NameBinding @NameBinding
@Retention(RUNTIME) @Retention(RUNTIME)
@Target({ METHOD }) @Target({ METHOD })

View File

@ -1,12 +1,32 @@
package org.kar.archidata.api; package org.kar.archidata.api;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import javax.imageio.ImageIO;
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.filter.GenericContext;
import org.kar.archidata.model.Data;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.annotation.security.PermitTokenInURI; import org.kar.archidata.annotation.security.PermitTokenInURI;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.annotation.security.RolesAllowed;
import org.kar.archidata.filter.GenericContext;
import org.kar.archidata.model.Data;
import org.kar.archidata.sqlWrapper.QuerryCondition;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.util.ConfigBaseVariable; import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -28,25 +48,13 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.SecurityContext;
import jakarta.ws.rs.core.StreamingOutput; import jakarta.ws.rs.core.StreamingOutput;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
// https://stackoverflow.com/questions/35367113/jersey-webservice-scalable-approach-to-download-file-and-reply-to-client // https://stackoverflow.com/questions/35367113/jersey-webservice-scalable-approach-to-download-file-and-reply-to-client
// https://gist.github.com/aitoroses/4f7a2b197b732a6a691d // https://gist.github.com/aitoroses/4f7a2b197b732a6a691d
@Path("/data") @Path("/data")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public class DataResource { public class DataResource {
static final Logger logger = LoggerFactory.getLogger(MediaType.class); private static final Logger LOGGER = LoggerFactory.getLogger(MediaType.class);
private final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks private final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
/** /**
@ -86,9 +94,9 @@ public class DataResource {
} }
public static Data getWithSha512(String sha512) { public static Data getWithSha512(String sha512) {
logger.info("find sha512 = {}", sha512); LOGGER.info("find sha512 = {}", sha512);
try { try {
return SqlWrapper.getWhere(Data.class, "sha512", "=", sha512); return SqlWrapper.getWhere(Data.class, new QuerryCondition("sha512", "=", sha512));
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@ -97,7 +105,7 @@ public class DataResource {
} }
public static Data getWithId(long id) { public static Data getWithId(long id) {
logger.info("find id = {}", id); LOGGER.info("find id = {}", id);
try { try {
return SqlWrapper.get(Data.class, id); return SqlWrapper.get(Data.class, id);
} catch (Exception e) { } catch (Exception e) {
@ -148,10 +156,10 @@ public class DataResource {
return null; return null;
} }
String mediaPath = getFileData(injectedData.id); String mediaPath = getFileData(injectedData.id);
logger.info("src = {}", tmpPath); LOGGER.info("src = {}", tmpPath);
logger.info("dst = {}", mediaPath); LOGGER.info("dst = {}", mediaPath);
Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE); Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
logger.info("Move done"); LOGGER.info("Move done");
return injectedData; return injectedData;
} }
@ -165,7 +173,7 @@ public class DataResource {
try { try {
Files.delete(Paths.get(filepath)); Files.delete(Paths.get(filepath));
} catch (IOException e) { } catch (IOException e) {
logger.info("can not delete temporary file : {}", Paths.get(filepath)); LOGGER.info("can not delete temporary file : {}", Paths.get(filepath));
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -175,8 +183,7 @@ public class DataResource {
static String saveFile(InputStream uploadedInputStream, String serverLocation) { static String saveFile(InputStream uploadedInputStream, String serverLocation) {
String out = ""; String out = "";
try { try {
OutputStream outpuStream = new FileOutputStream(new File( OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
serverLocation));
int read = 0; int read = 0;
byte[] bytes = new byte[CHUNK_SIZE_IN]; byte[] bytes = new byte[CHUNK_SIZE_IN];
MessageDigest md = MessageDigest.getInstance("SHA-512"); MessageDigest md = MessageDigest.getInstance("SHA-512");
@ -187,7 +194,7 @@ public class DataResource {
md.update(bytes, 0, read); md.update(bytes, 0, read);
outpuStream.write(bytes, 0, read); outpuStream.write(bytes, 0, read);
} }
logger.info("Flush input stream ... {}", serverLocation); LOGGER.info("Flush input stream ... {}", serverLocation);
System.out.flush(); System.out.flush();
outpuStream.flush(); outpuStream.flush();
outpuStream.close(); outpuStream.close();
@ -197,10 +204,10 @@ public class DataResource {
out = bytesToHex(sha512Digest); out = bytesToHex(sha512Digest);
uploadedInputStream.close(); uploadedInputStream.close();
} catch (IOException ex) { } catch (IOException ex) {
logger.info("Can not write in temporary file ... "); LOGGER.info("Can not write in temporary file ... ");
ex.printStackTrace(); ex.printStackTrace();
} catch (NoSuchAlgorithmException ex) { } catch (NoSuchAlgorithmException ex) {
logger.info("Can not find sha512 algorithms"); LOGGER.info("Can not find sha512 algorithms");
ex.printStackTrace(); ex.printStackTrace();
} }
return out; return out;
@ -214,7 +221,6 @@ public class DataResource {
return sb.toString(); return sb.toString();
} }
public Data getSmall(Long id) { public Data getSmall(Long id) {
try { try {
return SqlWrapper.get(Data.class, id); return SqlWrapper.get(Data.class, id);
@ -231,11 +237,11 @@ public class DataResource {
@RolesAllowed("ADMIN") @RolesAllowed("ADMIN")
public Response uploadFile(@Context SecurityContext sc, @FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition fileMetaData) { public Response uploadFile(@Context SecurityContext sc, @FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition fileMetaData) {
GenericContext gc = (GenericContext) sc.getUserPrincipal(); GenericContext gc = (GenericContext) sc.getUserPrincipal();
logger.info("==================================================="); LOGGER.info("===================================================");
logger.info("== DATA uploadFile {}", (gc==null?"null":gc.userByToken)); LOGGER.info("== DATA uploadFile {}", (gc == null ? "null" : gc.userByToken));
logger.info("==================================================="); LOGGER.info("===================================================");
//public NodeSmall uploadFile(final FormDataMultiPart form) { //public NodeSmall uploadFile(final FormDataMultiPart form) {
logger.info("Upload file: "); LOGGER.info("Upload file: ");
String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++; String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
try { try {
createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator); createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
@ -255,14 +261,11 @@ public class DataResource {
public Response retriveDataId(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception { public Response retriveDataId(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal(); GenericContext gc = (GenericContext) sc.getUserPrincipal();
//logger.info("==================================================="); //logger.info("===================================================");
logger.info("== DATA retriveDataId ? id={} user={}", id, (gc==null?"null":gc.userByToken)); LOGGER.info("== DATA retriveDataId ? id={} user={}", id, (gc == null ? "null" : gc.userByToken));
//logger.info("==================================================="); //logger.info("===================================================");
Data value = getSmall(id); Data value = getSmall(id);
if (value == null) { if (value == null) {
Response.status(404). Response.status(404).entity("media NOT FOUND: " + id).type("text/plain").build();
entity("media NOT FOUND: " + id).
type("text/plain").
build();
} }
return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType); return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
} }
@ -273,31 +276,22 @@ public class DataResource {
@PermitTokenInURI @PermitTokenInURI
@Produces(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_OCTET_STREAM)
//@CacheMaxAge(time = 10, unit = TimeUnit.DAYS) //@CacheMaxAge(time = 10, unit = TimeUnit.DAYS)
public Response retriveDataThumbnailId(@Context SecurityContext sc, public Response retriveDataThumbnailId(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id)
@QueryParam(HttpHeaders.AUTHORIZATION) String token, throws Exception {
@HeaderParam("Range") String range,
@PathParam("id") Long id) throws Exception {
//GenericContext gc = (GenericContext) sc.getUserPrincipal(); //GenericContext gc = (GenericContext) sc.getUserPrincipal();
//logger.info("==================================================="); //logger.info("===================================================");
//logger.info("== DATA retriveDataThumbnailId ? {}", (gc==null?"null":gc.user)); //logger.info("== DATA retriveDataThumbnailId ? {}", (gc==null?"null":gc.user));
//logger.info("==================================================="); //logger.info("===================================================");
Data value = getSmall(id); Data value = getSmall(id);
if (value == null) { if (value == null) {
return Response.status(404). return Response.status(404).entity("media NOT FOUND: " + id).type("text/plain").build();
entity("media NOT FOUND: " + id).
type("text/plain").
build();
} }
String filePathName = ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data"; String filePathName = ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data";
File inputFile = new File(filePathName); File inputFile = new File(filePathName);
if (!inputFile.exists()) { if (!inputFile.exists()) {
return Response.status(404). return Response.status(404).entity("{\"error\":\"media Does not exist: " + id + "\"}").type("application/json").build();
entity("{\"error\":\"media Does not exist: " + id + "\"}").
type("application/json").
build();
} }
if ( value.mimeType.contentEquals("image/jpeg") if (value.mimeType.contentEquals("image/jpeg") || value.mimeType.contentEquals("image/png")
|| value.mimeType.contentEquals("image/png")
// || value.mimeType.contentEquals("image/webp") // || value.mimeType.contentEquals("image/webp")
) { ) {
// reads input image // reads input image
@ -305,8 +299,7 @@ public class DataResource {
int scaledWidth = 250; int scaledWidth = 250;
int scaledHeight = (int) ((float) inputImage.getHeight() / (float) inputImage.getWidth() * (float) scaledWidth); int scaledHeight = (int) ((float) inputImage.getHeight() / (float) inputImage.getWidth() * (float) scaledWidth);
// creates output image // creates output image
BufferedImage outputImage = new BufferedImage(scaledWidth, BufferedImage outputImage = new BufferedImage(scaledWidth, scaledHeight, inputImage.getType());
scaledHeight, inputImage.getType());
// scales the input image to the output image // scales the input image to the output image
Graphics2D g2d = outputImage.createGraphics(); Graphics2D g2d = outputImage.createGraphics();
@ -319,15 +312,11 @@ public class DataResource {
ImageIO.write(outputImage, "JPG", baos); ImageIO.write(outputImage, "JPG", baos);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return Response.status(500). return Response.status(500).entity("Internal Error: resize fail: " + e.getMessage()).type("text/plain").build();
entity("Internal Error: resize fail: " + e.getMessage()).
type("text/plain").
build();
} }
byte[] imageData = baos.toByteArray(); byte[] imageData = baos.toByteArray();
//Response.ok(new ByteArrayInputStream(imageData)).build(); //Response.ok(new ByteArrayInputStream(imageData)).build();
Response.ResponseBuilder out = Response.ok(imageData) Response.ResponseBuilder out = Response.ok(imageData).header(HttpHeaders.CONTENT_LENGTH, imageData.length);
.header(HttpHeaders.CONTENT_LENGTH, imageData.length);
out.type("image/jpeg"); out.type("image/jpeg");
// TODO: move this in a decorator !!! // TODO: move this in a decorator !!!
CacheControl cc = new CacheControl(); CacheControl cc = new CacheControl();
@ -338,23 +327,22 @@ public class DataResource {
} }
return buildStream(filePathName, range, value.mimeType); return buildStream(filePathName, range, value.mimeType);
} }
//@Secured //@Secured
@GET @GET
@Path("{id}/{name}") @Path("{id}/{name}")
@PermitTokenInURI @PermitTokenInURI
@RolesAllowed("USER") @RolesAllowed("USER")
@Produces(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response retriveDataFull(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id, @PathParam("name") String name) throws Exception { public Response retriveDataFull(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id,
@PathParam("name") String name) throws Exception {
GenericContext gc = (GenericContext) sc.getUserPrincipal(); GenericContext gc = (GenericContext) sc.getUserPrincipal();
//logger.info("==================================================="); //logger.info("===================================================");
logger.info("== DATA retriveDataFull ? id={} user={}", id, (gc==null?"null":gc.userByToken)); LOGGER.info("== DATA retriveDataFull ? id={} user={}", id, (gc == null ? "null" : gc.userByToken));
//logger.info("==================================================="); //logger.info("===================================================");
Data value = getSmall(id); Data value = getSmall(id);
if (value == null) { if (value == null) {
Response.status(404). Response.status(404).entity("media NOT FOUND: " + id).type("text/plain").build();
entity("media NOT FOUND: " + id).
type("text/plain").
build();
} }
return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType); return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
} }
@ -383,7 +371,7 @@ public class DataResource {
out.flush(); out.flush();
//logger.info("---- wrote {} bytes file ----", len); //logger.info("---- wrote {} bytes file ----", len);
} catch (IOException ex) { } catch (IOException ex) {
logger.info("remote close connection"); LOGGER.info("remote close connection");
break; break;
} }
} }
@ -392,8 +380,7 @@ public class DataResource {
} }
} }
}; };
Response.ResponseBuilder out = Response.ok(output) Response.ResponseBuilder out = Response.ok(output).header(HttpHeaders.CONTENT_LENGTH, file.length());
.header(HttpHeaders.CONTENT_LENGTH, file.length());
if (mimeType != null) { if (mimeType != null) {
out.type(mimeType); out.type(mimeType);
} }
@ -421,12 +408,8 @@ public class DataResource {
final long len = to - from + 1; final long len = to - from + 1;
final MediaStreamer streamer = new MediaStreamer(len, raf); final MediaStreamer streamer = new MediaStreamer(len, raf);
Response.ResponseBuilder out = Response.ok(streamer) Response.ResponseBuilder out = Response.ok(streamer).status(Response.Status.PARTIAL_CONTENT).header("Accept-Ranges", "bytes").header("Content-Range", responseRange)
.status(Response.Status.PARTIAL_CONTENT) .header(HttpHeaders.CONTENT_LENGTH, streamer.getLenth()).header(HttpHeaders.LAST_MODIFIED, new Date(file.lastModified()));
.header("Accept-Ranges", "bytes")
.header("Content-Range", responseRange)
.header(HttpHeaders.CONTENT_LENGTH, streamer.getLenth())
.header(HttpHeaders.LAST_MODIFIED, new Date(file.lastModified()));
if (mimeType != null) { if (mimeType != null) {
out.type(mimeType); out.type(mimeType);
} }

View File

@ -3,19 +3,22 @@ package org.kar.archidata.api;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import jakarta.ws.rs.*; import org.kar.archidata.annotation.security.PermitAll;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.NotSupportedException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.CacheControl; import jakarta.ws.rs.core.CacheControl;
import jakarta.ws.rs.core.PathSegment; import jakarta.ws.rs.core.PathSegment;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder; import jakarta.ws.rs.core.Response.ResponseBuilder;
import org.kar.archidata.annotation.security.PermitAll;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FrontGeneric { public class FrontGeneric {
static final Logger logger = LoggerFactory.getLogger(FrontGeneric.class); private static final Logger LOGGER = LoggerFactory.getLogger(FrontGeneric.class);
protected String baseFrontFolder = "/data/front"; protected String baseFrontFolder = "/data/front";
@ -25,11 +28,12 @@ public class FrontGeneric {
} }
return ""; return "";
} }
private Response retrive(String fileName) throws Exception { private Response retrive(String fileName) throws Exception {
String filePathName = baseFrontFolder + File.separator + fileName; String filePathName = baseFrontFolder + File.separator + fileName;
String extention = getExtension(filePathName); String extention = getExtension(filePathName);
String mineType = null; String mineType = null;
logger.debug("try retrive : '{}' '{}'", filePathName, extention); LOGGER.debug("try retrive : '{}' '{}'", filePathName, extention);
if (extention.length() != 0 && extention.length() <= 5) { if (extention.length() != 0 && extention.length() <= 5) {
if (extention.equalsIgnoreCase("jpg") || extention.equalsIgnoreCase("jpeg")) { if (extention.equalsIgnoreCase("jpg") || extention.equalsIgnoreCase("jpeg")) {
mineType = "image/jpeg"; mineType = "image/jpeg";
@ -51,6 +55,12 @@ public class FrontGeneric {
mineType = "text/html"; mineType = "text/html";
} else if (extention.equalsIgnoreCase("css")) { } else if (extention.equalsIgnoreCase("css")) {
mineType = "text/css"; mineType = "text/css";
} else if (extention.equalsIgnoreCase("mka")) {
mineType = "audio/x-matroska";
} else if (extention.equalsIgnoreCase("mkv")) {
mineType = "video/x-matroska";
} else if (extention.equalsIgnoreCase("webm")) {
mineType = "video/webm";
} else { } else {
throw new NotSupportedException("Not supported model: '" + fileName + "'"); throw new NotSupportedException("Not supported model: '" + fileName + "'");
} }
@ -58,7 +68,7 @@ public class FrontGeneric {
mineType = "text/html"; mineType = "text/html";
filePathName = baseFrontFolder + File.separator + "index.html"; filePathName = baseFrontFolder + File.separator + "index.html";
} }
logger.debug(" ==> '[}'", filePathName); LOGGER.debug(" ==> '[}'", filePathName);
// reads input image // reads input image
File download = new File(filePathName); File download = new File(filePathName);
if (!download.exists()) { if (!download.exists()) {

View File

@ -1,8 +1,5 @@
package org.kar.archidata.api; package org.kar.archidata.api;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.StreamingOutput;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
@ -10,8 +7,12 @@ import java.io.RandomAccessFile;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.StreamingOutput;
public class MediaStreamer implements StreamingOutput { public class MediaStreamer implements StreamingOutput {
static final Logger logger = LoggerFactory.getLogger(MediaStreamer.class); private static final Logger LOGGER = LoggerFactory.getLogger(MediaStreamer.class);
private final int CHUNK_SIZE = 1024 * 1024; // 1MB chunks private final int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
final byte[] buf = new byte[CHUNK_SIZE]; final byte[] buf = new byte[CHUNK_SIZE];
private long length; private long length;
@ -34,7 +35,7 @@ public class MediaStreamer implements StreamingOutput {
try { try {
outputStream.write(buf, 0, read); outputStream.write(buf, 0, read);
} catch (IOException ex) { } catch (IOException ex) {
logger.info("remote close connection"); LOGGER.info("remote close connection");
break; break;
} }
length -= read; length -= read;

View File

@ -1,25 +1,22 @@
package org.kar.archidata.catcher; package org.kar.archidata.catcher;
import jakarta.ws.rs.core.MediaType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
public class ExceptionCatcher implements ExceptionMapper<Exception> {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatcher.class);
public class ExceptionCatcher
implements ExceptionMapper<Exception> {
final Logger logger = LoggerFactory.getLogger(ExceptionCatcher.class);
@Override @Override
public Response toResponse(Exception exception) { public Response toResponse(Exception exception) {
logger.warn("Catch exception (not managed...):"); LOGGER.warn("Catch exception (not managed...):");
RestErrorResponse ret = build(exception); RestErrorResponse ret = build(exception);
logger.error("Error UUID={}", ret.uuid); LOGGER.error("Error UUID={}", ret.uuid);
exception.printStackTrace(); exception.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR) return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ret).type(MediaType.APPLICATION_JSON).build();
.entity(ret)
.type(MediaType.APPLICATION_JSON)
.build();
} }
private RestErrorResponse build(Exception exception) { private RestErrorResponse build(Exception exception) {

View File

@ -1,25 +1,21 @@
package org.kar.archidata.catcher; package org.kar.archidata.catcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.ClientErrorException; import jakarta.ws.rs.ClientErrorException;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import org.slf4j.Logger; public class FailException404API implements ExceptionMapper<ClientErrorException> {
import org.slf4j.LoggerFactory; private static final Logger LOGGER = LoggerFactory.getLogger(FailException404API.class);
public class FailException404API
implements ExceptionMapper<ClientErrorException> {
final Logger logger = LoggerFactory.getLogger(FailException404API.class);
@Override @Override
public Response toResponse(ClientErrorException exception) { public Response toResponse(ClientErrorException exception) {
RestErrorResponse ret = build(exception); RestErrorResponse ret = build(exception);
logger.error("Error UUID={}", ret.uuid); LOGGER.error("Error UUID={}", ret.uuid);
return Response.status(exception.getResponse().getStatusInfo().toEnum()) return Response.status(exception.getResponse().getStatusInfo().toEnum()).entity(ret).type(MediaType.APPLICATION_JSON).build();
.entity(ret)
.type(MediaType.APPLICATION_JSON)
.build();
} }
private RestErrorResponse build(ClientErrorException exception) { private RestErrorResponse build(ClientErrorException exception) {

View File

@ -1,27 +1,23 @@
package org.kar.archidata.catcher; package org.kar.archidata.catcher;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.kar.archidata.exception.FailException; import org.kar.archidata.exception.FailException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
public class FailExceptionCatcher implements ExceptionMapper<FailException> {
private static final Logger LOGGER = LoggerFactory.getLogger(FailExceptionCatcher.class);
public class FailExceptionCatcher
implements ExceptionMapper<FailException> {
final Logger logger = LoggerFactory.getLogger(FailExceptionCatcher.class);
@Override @Override
public Response toResponse(FailException exception) { public Response toResponse(FailException exception) {
RestErrorResponse ret = build(exception); RestErrorResponse ret = build(exception);
logger.error("Error UUID={}", ret.uuid); LOGGER.error("Error UUID={}", ret.uuid);
// Not display backtrace ==> this may be a normal case ... // Not display backtrace ==> this may be a normal case ...
//exception.printStackTrace(); //exception.printStackTrace();
return Response.status(exception.status) return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
.entity(ret)
.type(MediaType.APPLICATION_JSON)
.build();
} }
private RestErrorResponse build(FailException exception) { private RestErrorResponse build(FailException exception) {

View File

@ -1,26 +1,22 @@
package org.kar.archidata.catcher; package org.kar.archidata.catcher;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.kar.archidata.exception.InputException; import org.kar.archidata.exception.InputException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
public class InputExceptionCatcher implements ExceptionMapper<InputException> {
private static final Logger LOGGER = LoggerFactory.getLogger(InputExceptionCatcher.class);
public class InputExceptionCatcher
implements ExceptionMapper<InputException> {
final Logger logger = LoggerFactory.getLogger(InputExceptionCatcher.class);
@Override @Override
public Response toResponse(InputException exception) { public Response toResponse(InputException exception) {
RestErrorResponse ret = build(exception); RestErrorResponse ret = build(exception);
logger.error("Error UUID={}", ret.uuid); LOGGER.error("Error UUID={}", ret.uuid);
exception.printStackTrace(); exception.printStackTrace();
return Response.status(exception.status) return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
.entity(ret)
.type(MediaType.APPLICATION_JSON)
.build();
} }
private RestErrorResponse build(InputException exception) { private RestErrorResponse build(InputException exception) {

View File

@ -20,6 +20,7 @@ public class RestErrorResponse {
this.status = status.getStatusCode(); this.status = status.getStatusCode();
this.statusMessage = status.getReasonPhrase(); this.statusMessage = status.getReasonPhrase();
} }
public RestErrorResponse(Response.Status status, String error, String message) { public RestErrorResponse(Response.Status status, String error, String message) {
this.time = Instant.now().toString(); this.time = Instant.now().toString();
this.error = error; this.error = error;
@ -27,6 +28,7 @@ public class RestErrorResponse {
this.status = status.getStatusCode(); this.status = status.getStatusCode();
this.statusMessage = status.getReasonPhrase(); this.statusMessage = status.getReasonPhrase();
} }
public RestErrorResponse(Response.Status status) { public RestErrorResponse(Response.Status status) {
this.time = Instant.now().toString(); this.time = Instant.now().toString();
this.status = status.getStatusCode(); this.status = status.getStatusCode();

View File

@ -1,26 +1,22 @@
package org.kar.archidata.catcher; package org.kar.archidata.catcher;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.kar.archidata.exception.SystemException; import org.kar.archidata.exception.SystemException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
public class SystemExceptionCatcher implements ExceptionMapper<SystemException> {
private static final Logger LOGGER = LoggerFactory.getLogger(SystemExceptionCatcher.class);
public class SystemExceptionCatcher
implements ExceptionMapper<SystemException> {
final Logger logger = LoggerFactory.getLogger(SystemExceptionCatcher.class);
@Override @Override
public Response toResponse(SystemException exception) { public Response toResponse(SystemException exception) {
RestErrorResponse ret = build(exception); RestErrorResponse ret = build(exception);
logger.error("Error UUID={}", ret.uuid); LOGGER.error("Error UUID={}", ret.uuid);
exception.printStackTrace(); exception.printStackTrace();
return Response.status(exception.status) return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
.entity(ret)
.type(MediaType.APPLICATION_JSON)
.build();
} }
private RestErrorResponse build(SystemException exception) { private RestErrorResponse build(SystemException exception) {

View File

@ -38,14 +38,7 @@ public class DBConfig {
@Override @Override
public String toString() { public String toString() {
return "DBConfig{" + return "DBConfig{type='" + type + '\'' + ", hostname='" + hostname + '\'' + ", port=" + port + ", login='" + login + '\'' + ", password='" + password + '\'' + ", dbName='" + dbName + "' }";
"type='" + type + '\'' +
", hostname='" + hostname + '\'' +
", port=" + port +
", login='" + login + '\'' +
", password='" + password + '\'' +
", dbName='" + dbName + '\'' +
'}';
} }
public String getHostname() { public String getHostname() {
@ -67,6 +60,7 @@ public class DBConfig {
public String getDbName() { public String getDbName() {
return dbName; return dbName;
} }
public boolean getKeepConnected() { public boolean getKeepConnected() {
return keepConnected; return keepConnected;
} }
@ -74,6 +68,7 @@ public class DBConfig {
public String getUrl() { public String getUrl() {
return getUrl(false); return getUrl(false);
} }
public String getUrl(boolean isRoot) { public String getUrl(boolean isRoot) {
if (type.equals("sqlite")) { if (type.equals("sqlite")) {
if (isRoot == true) { if (isRoot == true) {

View File

@ -2,7 +2,9 @@ package org.kar.archidata.db;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.sql.*; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -27,6 +29,7 @@ public class DBEntry implements Closeable {
public static DBEntry createInterface(DBConfig config) throws IOException { public static DBEntry createInterface(DBConfig config) throws IOException {
return createInterface(config, false); return createInterface(config, false);
} }
public static DBEntry createInterface(DBConfig config, boolean root) throws IOException { public static DBEntry createInterface(DBConfig config, boolean root) throws IOException {
if (config.getKeepConnected()) { if (config.getKeepConnected()) {
for (DBEntry elem : stored) { for (DBEntry elem : stored) {

View File

@ -5,10 +5,12 @@ import jakarta.ws.rs.core.Response;
public class FailException extends Exception { public class FailException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public final Response.Status status; public final Response.Status status;
public FailException(Response.Status status, String message) { public FailException(Response.Status status, String message) {
super(message); super(message);
this.status = status; this.status = status;
} }
public FailException(String message) { public FailException(String message) {
super(message); super(message);
this.status = Response.Status.BAD_REQUEST; this.status = Response.Status.BAD_REQUEST;

View File

@ -6,11 +6,13 @@ public class InputException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public final String missingVariable; public final String missingVariable;
public final Response.Status status; public final Response.Status status;
public InputException(Response.Status status, String variable, String message) { public InputException(Response.Status status, String variable, String message) {
super(message); super(message);
this.missingVariable = variable; this.missingVariable = variable;
this.status = status; this.status = status;
} }
public InputException(String variable, String message) { public InputException(String variable, String message) {
super(message); super(message);
this.missingVariable = variable; this.missingVariable = variable;

View File

@ -4,6 +4,7 @@ import jakarta.ws.rs.core.Response;
public class NotFoundException extends FailException { public class NotFoundException extends FailException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public NotFoundException(String message) { public NotFoundException(String message) {
super(Response.Status.NOT_FOUND, message); super(Response.Status.NOT_FOUND, message);
} }

View File

@ -19,8 +19,8 @@ public class RESTErrorResponseExeption extends Exception {
this.status = 0; this.status = 0;
this.statusMessage = null; this.statusMessage = null;
} }
public RESTErrorResponseExeption(UUID uuid, String time, String error, String message, int status,
String statusMessage) { public RESTErrorResponseExeption(UUID uuid, String time, String error, String message, int status, String statusMessage) {
super(); super();
this.uuid = uuid; this.uuid = uuid;
this.time = time; this.time = time;
@ -32,10 +32,7 @@ public class RESTErrorResponseExeption extends Exception {
@Override @Override
public String toString() { public String toString() {
return "RESTErrorResponseExeption [uuid=" + uuid + ", time=" + time + ", error=" + error + ", message=" return "RESTErrorResponseExeption [uuid=" + uuid + ", time=" + time + ", error=" + error + ", message=" + message + ", status=" + status + ", statusMessage=" + statusMessage + "]";
+ message + ", status=" + status + ", statusMessage=" + statusMessage + "]";
} }
} }

View File

@ -5,10 +5,12 @@ import jakarta.ws.rs.core.Response;
public class SystemException extends Exception { public class SystemException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public final Response.Status status; public final Response.Status status;
public SystemException(Response.Status status, String message) { public SystemException(Response.Status status, String message) {
super(message); super(message);
this.status = status; this.status = status;
} }
public SystemException(String message) { public SystemException(String message) {
super(message); super(message);
this.status = Response.Status.INTERNAL_SERVER_ERROR; this.status = Response.Status.INTERNAL_SERVER_ERROR;

View File

@ -4,6 +4,7 @@ import jakarta.ws.rs.core.Response;
public class UnAuthorizedException extends FailException { public class UnAuthorizedException extends FailException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public UnAuthorizedException(String message) { public UnAuthorizedException(String message) {
super(Response.Status.UNAUTHORIZED, message); super(Response.Status.UNAUTHORIZED, message);
} }

View File

@ -1,10 +1,26 @@
package org.kar.archidata.filter; package org.kar.archidata.filter;
import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey/45814178#45814178
// https://stackoverflow.com/questions/32817210/how-to-access-jersey-resource-secured-by-rolesallowed
import org.kar.archidata.annotation.security.DenyAll; import org.kar.archidata.annotation.security.DenyAll;
import org.kar.archidata.annotation.security.PermitAll; import org.kar.archidata.annotation.security.PermitAll;
import org.kar.archidata.annotation.security.PermitTokenInURI;
import org.kar.archidata.annotation.security.RolesAllowed; import org.kar.archidata.annotation.security.RolesAllowed;
import org.kar.archidata.catcher.RestErrorResponse; import org.kar.archidata.catcher.RestErrorResponse;
import org.kar.archidata.model.UserByToken;
import org.kar.archidata.util.JWTWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
import jakarta.annotation.Priority; import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities; import jakarta.ws.rs.Priorities;
@ -18,23 +34,6 @@ import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
import org.kar.archidata.annotation.security.PermitTokenInURI;
import org.kar.archidata.model.UserByToken;
import org.kar.archidata.util.JWTWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey/45814178#45814178
// https://stackoverflow.com/questions/32817210/how-to-access-jersey-resource-secured-by-rolesallowed
//@PreMatching //@PreMatching
@Provider @Provider
@Priority(Priorities.AUTHENTICATION) @Priority(Priorities.AUTHENTICATION)
@ -47,8 +46,6 @@ public class AuthenticationFilter implements ContainerRequestFilter {
private static final String AUTHENTICATION_SCHEME = "Yota"; private static final String AUTHENTICATION_SCHEME = "Yota";
private static final String AUTHENTICATION_TOKEN_SCHEME = "Zota"; private static final String AUTHENTICATION_TOKEN_SCHEME = "Zota";
public AuthenticationFilter(String applicationName) { public AuthenticationFilter(String applicationName) {
super(); super();
this.applicationName = applicationName; this.applicationName = applicationName;
@ -179,7 +176,6 @@ public class AuthenticationFilter implements ContainerRequestFilter {
return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_TOKEN_SCHEME.toLowerCase() + " "); return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_TOKEN_SCHEME.toLowerCase() + " ");
} }
private void abortWithUnauthorized(ContainerRequestContext requestContext, String message) { private void abortWithUnauthorized(ContainerRequestContext requestContext, String message) {
// Abort the filter chain with a 401 status code response // Abort the filter chain with a 401 status code response
@ -187,18 +183,15 @@ public class AuthenticationFilter implements ContainerRequestFilter {
logger.warn("abortWithUnauthorized:"); logger.warn("abortWithUnauthorized:");
RestErrorResponse ret = new RestErrorResponse(Response.Status.UNAUTHORIZED, "Unauthorized", message); RestErrorResponse ret = new RestErrorResponse(Response.Status.UNAUTHORIZED, "Unauthorized", message);
logger.error("Error UUID={}", ret.uuid); logger.error("Error UUID={}", ret.uuid);
requestContext.abortWith(Response.status(ret.status) requestContext.abortWith(Response.status(ret.status).header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME + " base64(HEADER).base64(CONTENT).base64(KEY)").entity(ret)
.header(HttpHeaders.WWW_AUTHENTICATE, .type(MediaType.APPLICATION_JSON).build());
AUTHENTICATION_SCHEME + " base64(HEADER).base64(CONTENT).base64(KEY)")
.entity(ret)
.type(MediaType.APPLICATION_JSON)
.build());
} }
protected UserByToken validateToken(String authorization) throws Exception { protected UserByToken validateToken(String authorization) throws Exception {
logger.info("Must be Override by the application implmentation, otherwise it dose not work"); logger.info("Must be Override by the application implmentation, otherwise it dose not work");
return null; return null;
} }
// must be override to be good implementation // must be override to be good implementation
protected UserByToken validateJwtToken(String authorization) throws Exception { protected UserByToken validateJwtToken(String authorization) throws Exception {
//logger.debug(" validate token : " + authorization); //logger.debug(" validate token : " + authorization);

View File

@ -1,25 +1,23 @@
package org.kar.archidata.filter; package org.kar.archidata.filter;
import java.io.IOException;
import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext; import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.container.ContainerResponseFilter;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
import java.io.IOException;
@Provider @Provider
public class CORSFilter implements ContainerResponseFilter { public class CORSFilter implements ContainerResponseFilter {
@Override @Override
public void filter(ContainerRequestContext request, public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException {
ContainerResponseContext response) throws IOException {
//System.err.println("filter cors ..." + request.toString()); //System.err.println("filter cors ..." + request.toString());
response.getHeaders().add("Access-Control-Allow-Origin", "*"); response.getHeaders().add("Access-Control-Allow-Origin", "*");
response.getHeaders().add("Access-Control-Allow-Headers", "*"); response.getHeaders().add("Access-Control-Allow-Headers", "*");
// "Origin, content-type, Content-type, Accept, authorization, mime-type, filename"); // "Origin, content-type, Content-type, Accept, authorization, mime-type, filename");
response.getHeaders().add("Access-Control-Allow-Credentials", "true"); response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods", response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
} }
} }

View File

@ -1,9 +1,9 @@
package org.kar.archidata.filter; package org.kar.archidata.filter;
import org.kar.archidata.model.UserByToken;
import java.security.Principal; import java.security.Principal;
import org.kar.archidata.model.UserByToken;
public class GenericContext implements Principal { public class GenericContext implements Principal {
public UserByToken userByToken; public UserByToken userByToken;

View File

@ -1,9 +1,10 @@
package org.kar.archidata.filter; package org.kar.archidata.filter;
import java.security.Principal;
import org.kar.archidata.model.UserByToken; import org.kar.archidata.model.UserByToken;
import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.SecurityContext;
import java.security.Principal;
// https://simplapi.wordpress.com/2015/09/19/jersey-jax-rs-securitycontext-in-action/ // https://simplapi.wordpress.com/2015/09/19/jersey-jax-rs-securitycontext-in-action/
class MySecurityContext implements SecurityContext { class MySecurityContext implements SecurityContext {

View File

@ -1,11 +1,12 @@
package org.kar.archidata.filter; package org.kar.archidata.filter;
import java.io.IOException;
import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.PreMatching; import jakarta.ws.rs.container.PreMatching;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
import java.io.IOException;
@Provider @Provider
@PreMatching @PreMatching
@ -17,5 +18,3 @@ public class OptionFilter implements ContainerRequestFilter {
} }
} }
} }

View File

@ -25,6 +25,7 @@ public class MigrationEngine {
public MigrationEngine() { public MigrationEngine() {
this(new ArrayList<MigrationInterface>(), null); this(new ArrayList<MigrationInterface>(), null);
} }
/** /**
* Migration engine constructor (specific mode). * Migration engine constructor (specific mode).
* @param datas All the migration ordered. * @param datas All the migration ordered.
@ -34,6 +35,7 @@ public class MigrationEngine {
this.datas = datas; this.datas = datas;
this.init = init; this.init = init;
} }
/** /**
* Add a Migration in the list * Add a Migration in the list
* @param migration Migration to add. * @param migration Migration to add.
@ -41,6 +43,7 @@ public class MigrationEngine {
public void add(MigrationInterface migration) { public void add(MigrationInterface migration) {
this.datas.add(migration); this.datas.add(migration);
} }
/** /**
* Set first initialization class * Set first initialization class
* @param migration migration class for first init. * @param migration migration class for first init.
@ -48,6 +51,7 @@ public class MigrationEngine {
public void setInit(MigrationInterface migration) { public void setInit(MigrationInterface migration) {
init = migration; init = migration;
} }
/** /**
* Get the current version/migration name * Get the current version/migration name
* @return Model represent the last migration. If null then no migration has been done. * @return Model represent the last migration. If null then no migration has been done.
@ -77,6 +81,7 @@ public class MigrationEngine {
} }
return null; return null;
} }
/** /**
* Process the automatic migration of the system * Process the automatic migration of the system
* @param config SQL connection for the migration * @param config SQL connection for the migration
@ -187,6 +192,7 @@ public class MigrationEngine {
} }
LOGGER.info("Execute migration ... [ END ]"); LOGGER.info("Execute migration ... [ END ]");
} }
public void migrateSingle(DBEntry entry, MigrationInterface elem, int id, int count) { public void migrateSingle(DBEntry entry, MigrationInterface elem, int id, int count) {
LOGGER.info("Migrate: [{}/{}] {} [BEGIN]", id, count, elem.getName()); LOGGER.info("Migrate: [{}/{}] {} [BEGIN]", id, count, elem.getName());
StringBuilder log = new StringBuilder(); StringBuilder log = new StringBuilder();
@ -220,7 +226,8 @@ public class MigrationEngine {
e.printStackTrace(); e.printStackTrace();
} }
while (true) { while (true) {
LOGGER.error("An error occured in the migration (OUTSIDE detection): '{}' defect @{}/{} ==> wait administrator interventions", migrationResult.name , migrationResult.stepId, migrationResult.count); LOGGER.error("An error occured in the migration (OUTSIDE detection): '{}' defect @{}/{} ==> wait administrator interventions", migrationResult.name, migrationResult.stepId,
migrationResult.count);
try { try {
Thread.sleep(60 * 60 * 1000); Thread.sleep(60 * 60 * 1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -254,6 +261,7 @@ public class MigrationEngine {
revertSingle(entry, elem, id, count); revertSingle(entry, elem, id, count);
} }
} }
public void revertSingle(DBEntry entry, MigrationInterface elem, int id, int count) { public void revertSingle(DBEntry entry, MigrationInterface elem, int id, int count) {
LOGGER.info("Revert migration: {} [BEGIN]", elem.getName()); LOGGER.info("Revert migration: {} [BEGIN]", elem.getName());

View File

@ -8,6 +8,7 @@ public interface MigrationInterface {
* @return Migration name * @return Migration name
*/ */
String getName(); String getName();
/** /**
* Migrate the system to a new version. * Migrate the system to a new version.
* @param entry DB interface for the migration. * @param entry DB interface for the migration.
@ -16,6 +17,7 @@ public interface MigrationInterface {
* @return true if migration is finished. * @return true if migration is finished.
*/ */
boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model); boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model);
/** /**
* Remove a migration the system to the previous version. * Remove a migration the system to the previous version.
* @param entry DB interface for the migration. * @param entry DB interface for the migration.

View File

@ -3,24 +3,24 @@ package org.kar.archidata.migration;
import org.kar.archidata.annotation.SQLComment; import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLLimitSize;
import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLTableName;
import org.kar.archidata.model.GenericTable; import org.kar.archidata.model.GenericTable;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.persistence.Column;
import jakarta.persistence.Table;
// For logs only // For logs only
//public static final String TABLE_NAME = "KAR_migration"; //public static final String TABLE_NAME = "KAR_migration";
@SQLTableName ("KAR_migration") @Table(name = "KAR_migration")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class MigrationModel extends GenericTable { public class MigrationModel extends GenericTable {
@SQLComment("Name of the migration") @SQLComment("Name of the migration")
@SQLLimitSize(256) @Column(length = 256)
public String name; public String name;
@SQLNotNull @Column(nullable = false)
@SQLDefault("'0'") @SQLDefault("'0'")
@SQLComment("if the migration is well terminated or not") @SQLComment("if the migration is well terminated or not")
public Boolean terminated = false; public Boolean terminated = false;

View File

@ -12,19 +12,26 @@ import org.slf4j.LoggerFactory;
public class MigrationSqlStep implements MigrationInterface { public class MigrationSqlStep implements MigrationInterface {
final static Logger LOGGER = LoggerFactory.getLogger(MigrationSqlStep.class); final static Logger LOGGER = LoggerFactory.getLogger(MigrationSqlStep.class);
private List<String> actions = new ArrayList<>(); private final List<String> actions = new ArrayList<>();
@Override @Override
public String getName() { public String getName() {
return getClass().getCanonicalName(); return getClass().getCanonicalName();
} }
public void display() {
for (int iii = 0; iii < this.actions.size(); iii++) {
final String action = this.actions.get(iii);
LOGGER.info(" >>>> SQL ACTION : {}/{} ==> \n{}", iii, this.actions.size(), action);
}
}
@Override @Override
public boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model) { public boolean applyMigration(final DBEntry entry, final StringBuilder log, final MigrationModel model) {
for (int iii=0; iii<actions.size(); iii++) { for (int iii = 0; iii < this.actions.size(); iii++) {
log.append("action [" + iii + "/" + actions.size() + "]\n"); log.append("action [" + iii + "/" + this.actions.size() + "]\n");
LOGGER.info(" >>>> SQL ACTION : {}/{}", iii, actions.size()); LOGGER.info(" >>>> SQL ACTION : {}/{}", iii, this.actions.size());
String action = actions.get(iii); final String action = this.actions.get(iii);
LOGGER.info("SQL request: ```{}```", action); LOGGER.info("SQL request: ```{}```", action);
log.append("SQL: " + action + "\n"); log.append("SQL: " + action + "\n");
try { try {
@ -37,24 +44,24 @@ public class MigrationSqlStep implements MigrationInterface {
model.log = log.toString(); model.log = log.toString();
try { try {
SqlWrapper.update(model, model.id, List.of("stepId", "log")); SqlWrapper.update(model, model.id, List.of("stepId", "log"));
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return false; return false;
} }
log.append("action [" + iii + "/" + actions.size() + "] ==> DONE\n"); log.append("action [" + iii + "/" + this.actions.size() + "] ==> DONE\n");
LOGGER.info(" >>>> SQL ACTION : {}/{} ==> DONE", iii, actions.size()); LOGGER.info(" >>>> SQL ACTION : {}/{} ==> DONE", iii, this.actions.size());
model.stepId = iii + 1; model.stepId = iii + 1;
model.log = log.toString(); model.log = log.toString();
try { try {
SqlWrapper.update(model, model.id, List.of("stepId", "log")); SqlWrapper.update(model, model.id, List.of("stepId", "log"));
} catch (Exception e) { } catch (final Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
try { try {
Thread.sleep(100); Thread.sleep(100);
} catch (InterruptedException e) { } catch (final InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
@ -63,21 +70,22 @@ public class MigrationSqlStep implements MigrationInterface {
} }
@Override @Override
public boolean revertMigration(DBEntry entry, StringBuilder log) { public boolean revertMigration(final DBEntry entry, final StringBuilder log) {
return false; return false;
} }
public void addAction(String action) { public void addAction(final String action) {
actions.add(action); this.actions.add(action);
} }
public void addClass(Class<?> clazz) throws Exception {
List<String> tmp = SqlWrapper.createTable(clazz, false); public void addClass(final Class<?> clazz) throws Exception {
actions.addAll(tmp); final List<String> tmp = SqlWrapper.createTable(clazz, false);
this.actions.addAll(tmp);
} }
@Override @Override
public int getNumberOfStep() { public int getNumberOfStep() {
return actions.size(); return this.actions.size();
} }
} }

View File

@ -1,28 +1,25 @@
package org.kar.archidata.model; package org.kar.archidata.model;
import org.kar.archidata.annotation.SQLComment; import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLLimitSize;
import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLTableName;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("data") import jakarta.persistence.Column;
import jakarta.persistence.Table;
@Table(name = "data")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class Data extends GenericTable { public class Data extends GenericTable {
@SQLNotNull @Column(length = 128, nullable = false)
@SQLLimitSize(128)
@SQLComment("Sha512 of the data") @SQLComment("Sha512 of the data")
public String sha512; public String sha512;
@SQLNotNull @Column(length = 128, nullable = false)
@SQLLimitSize(128)
@SQLComment("Mime -type of the media") @SQLComment("Mime -type of the media")
public String mimeType; public String mimeType;
@SQLNotNull @Column(nullable = false)
@SQLComment("Size in Byte of the data") @SQLComment("Size in Byte of the data")
public Long size; public Long size;
} }

View File

@ -2,37 +2,39 @@ package org.kar.archidata.model;
import java.sql.Timestamp; import java.sql.Timestamp;
import org.kar.archidata.annotation.SQLAutoIncrement; import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.SQLComment; import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLCreateTime;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLDeleted; import org.kar.archidata.annotation.SQLDeleted;
import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLNotRead; import org.kar.archidata.annotation.SQLNotRead;
import org.kar.archidata.annotation.SQLPrimaryKey; import org.kar.archidata.annotation.UpdateTimestamp;
import org.kar.archidata.annotation.SQLUpdateTime;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
public class GenericTable { public class GenericTable {
@SQLAutoIncrement // Add AUTO_INCREMENT modifier @Id
@SQLPrimaryKey // Create a PRIMARY KEY based on this field @GeneratedValue(strategy = GenerationType.IDENTITY)
@SQLNotNull @Column(nullable = false, unique = true)
@SQLComment("Primary key of the base") @SQLComment("Primary key of the base")
public Long id = null; public Long id = null;
@SQLNotRead @SQLNotRead
@SQLNotNull @Column(nullable = false)
@SQLDefault("'0'") @SQLDefault("'0'")
@SQLDeleted @SQLDeleted
@SQLComment("When delete, they are not removed, they are just set in a deleted state") @SQLComment("When delete, they are not removed, they are just set in a deleted state")
public Boolean deleted = null; public Boolean deleted = null;
@SQLNotRead @SQLNotRead
@SQLCreateTime @CreationTimestamp
@SQLNotNull @Column(nullable = false)
@SQLComment("Create time of the object") @SQLComment("Create time of the object")
@SQLDefault("CURRENT_TIMESTAMP(3)") @SQLDefault("CURRENT_TIMESTAMP(3)")
public Timestamp create_date = null; public Timestamp create_date = null;
@SQLNotRead @SQLNotRead
@SQLUpdateTime @UpdateTimestamp
@SQLNotNull @Column(nullable = false)
@SQLComment("When update the object") @SQLComment("When update the object")
@SQLDefault("CURRENT_TIMESTAMP(3)") @SQLDefault("CURRENT_TIMESTAMP(3)")
public Timestamp modify_date = null; public Timestamp modify_date = null;

View File

@ -3,21 +3,22 @@ package org.kar.archidata.model;
import java.sql.Timestamp; import java.sql.Timestamp;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLTableName;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("applicationToken") import jakarta.persistence.Column;
import jakarta.persistence.Table;
@Table(name = "applicationToken")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class GenericToken extends GenericTable { public class GenericToken extends GenericTable {
@SQLNotNull @Column(nullable = false)
public Long parentId; public Long parentId;
@SQLNotNull @Column(nullable = false)
public String name; public String name;
@SQLNotNull @Column(nullable = false)
public Timestamp endValidityTime = null; public Timestamp endValidityTime = null;
@SQLNotNull @Column(nullable = false)
public String token; public String token;
} }

View File

@ -3,6 +3,7 @@ package org.kar.archidata.model;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public record GetToken(String jwt) { public record GetToken(
String jwt) {
} }

View File

@ -3,7 +3,6 @@ package org.kar.archidata.model;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
public class Token { public class Token {
public Long id; public Long id;
public Long userId; public Long userId;
@ -11,8 +10,7 @@ public class Token {
public String createTime; public String createTime;
public String endValidityTime; public String endValidityTime;
public Token() { public Token() {}
}
public Token(long id, long userId, String token, String createTime, String endValidityTime) { public Token(long id, long userId, String token, String createTime, String endValidityTime) {
this.id = id; this.id = id;
@ -37,12 +35,6 @@ public class Token {
@Override @Override
public String toString() { public String toString() {
return "Token{" + return "Token{" + "id=" + id + ", userId=" + userId + ", token='" + token + '\'' + ", createTime=" + createTime + ", endValidityTime=" + endValidityTime + '}';
"id=" + id +
", userId=" + userId +
", token='" + token + '\'' +
", createTime=" + createTime +
", endValidityTime=" + endValidityTime +
'}';
} }
} }

View File

@ -15,35 +15,43 @@ CREATE TABLE `user` (
*/ */
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.List;
import org.kar.archidata.annotation.SQLDefault; import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLLimitSize; import org.kar.archidata.sqlWrapper.Foreign;
import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLTableName;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@SQLTableName ("user") import jakarta.persistence.Column;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@Table(name = "user")
@SQLIfNotExists @SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class User extends GenericTable { public class User extends GenericTable {
@SQLLimitSize(128) @Column(length = 128)
public String login = null; public String login = null;
public Timestamp lastConnection = null; public Timestamp lastConnection = null;
@SQLDefault("'0'") @SQLDefault("'0'")
@SQLNotNull @Column(nullable = false)
public boolean admin = false; public boolean admin = false;
@SQLDefault("'0'") @SQLDefault("'0'")
@SQLNotNull @Column(nullable = false)
public boolean blocked = false; public boolean blocked = false;
@SQLDefault("'0'") @SQLDefault("'0'")
@SQLNotNull @Column(nullable = false)
public boolean removed = false; public boolean removed = false;
@ManyToOne(fetch = FetchType.LAZY)
public List<Foreign<Data>> covers;
@Override @Override
public String toString() { public String toString() {
return "User [login=" + login + ", last=" + lastConnection + ", admin=" + admin + "]"; return "User [login=" + this.login + ", last=" + this.lastConnection + ", admin=" + this.admin + "]";
} }
} }

View File

@ -3,7 +3,6 @@ package org.kar.archidata.model;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class UserByToken { public class UserByToken {
public static final int TYPE_USER = -1; public static final int TYPE_USER = -1;
public static final int TYPE_APPLICATION = -2; public static final int TYPE_APPLICATION = -2;

View File

@ -0,0 +1,16 @@
package org.kar.archidata.sqlWrapper;
public class Foreign<T> {
public final Long id;
public final T data;
public Foreign(final Long id) {
this.id = id;
this.data = null;
}
public Foreign(final T data) {
this.id = null;
this.data = data;
}
}

View File

@ -0,0 +1,11 @@
package org.kar.archidata.sqlWrapper;
import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalForeinKeyAsList;
import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalLink;
public class GenericAddOn {
public static void addGenericAddOn() {
SqlWrapper.addAddOn(new AddOnSQLTableExternalLink());
SqlWrapper.addAddOn(new AddOnSQLTableExternalForeinKeyAsList());
}
}

View File

@ -0,0 +1,43 @@
package org.kar.archidata.sqlWrapper;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
public class QuerryAnd implements QuerryItem {
protected final List<QuerryItem> childs;
public QuerryAnd(List<QuerryItem> childs) {
this.childs = childs;
}
public QuerryAnd(QuerryItem... items) {
this.childs = new ArrayList<>();
for (int iii = 0; iii < items.length; iii++) {
this.childs.add(items[iii]);
}
}
public void generateQuerry(StringBuilder querry, String tableName) {
querry.append(" (");
boolean first = false;
for (QuerryItem elem : this.childs) {
if (first) {
first = false;
} else {
querry.append(" AND ");
}
elem.generateQuerry(querry, tableName);
}
querry.append(")");
}
@Override
public int injectQuerry(PreparedStatement ps, int iii) throws Exception {
for (QuerryItem elem : this.childs) {
iii = elem.injectQuerry(ps, iii);
}
return iii;
}
}

View File

@ -0,0 +1,31 @@
package org.kar.archidata.sqlWrapper;
import java.sql.PreparedStatement;
public class QuerryCondition implements QuerryItem {
private final String key;
private final String comparator;
private final Object value;
public QuerryCondition(String key, String comparator, Object value) {
this.key = key;
this.comparator = comparator;
this.value = value;
}
public void generateQuerry(StringBuilder querry, String tableName) {
querry.append(tableName);
querry.append(".");
querry.append(this.key);
querry.append(" ");
querry.append(this.comparator);
querry.append(" ?");
}
@Override
public int injectQuerry(PreparedStatement ps, int iii) throws Exception {
SqlWrapper.addElement(ps, this.value, iii++);
return iii;
}
}

View File

@ -0,0 +1,9 @@
package org.kar.archidata.sqlWrapper;
import java.sql.PreparedStatement;
public interface QuerryItem {
void generateQuerry(StringBuilder querry, String tableName);
int injectQuerry(PreparedStatement ps, int iii) throws Exception;
}

View File

@ -0,0 +1,35 @@
package org.kar.archidata.sqlWrapper;
import java.sql.PreparedStatement;
import java.util.List;
public class QuerryOr implements QuerryItem {
protected final List<QuerryItem> childs;
public QuerryOr(List<QuerryItem> childs) {
this.childs = childs;
}
public void generateQuerry(StringBuilder querry, String tableName) {
querry.append(" (");
boolean first = false;
for (QuerryItem elem : this.childs) {
if (first) {
first = false;
} else {
querry.append(" OR ");
}
elem.generateQuerry(querry, tableName);
}
querry.append(")");
}
@Override
public int injectQuerry(PreparedStatement ps, int iii) throws Exception {
for (QuerryItem elem : this.childs) {
iii = elem.injectQuerry(ps, iii);
}
return iii;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,10 @@
package org.kar.archidata.sqlWrapper; package org.kar.archidata.sqlWrapper;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public interface SqlWrapperAddOn { public interface SqlWrapperAddOn {
/** /**
@ -8,12 +12,14 @@ public interface SqlWrapperAddOn {
* @return The annotation class * @return The annotation class
*/ */
Class<?> getAnnotationClass(); Class<?> getAnnotationClass();
/** /**
* Get the SQL type that is needed to declare for the specific Field Type. * Get the SQL type that is needed to declare for the specific Field Type.
* @param elem Field to declare. * @param elem Field to declare.
* @return SQL type to create. * @return SQL type to create.
*/ */
String getSQLFieldType(Field elem); String getSQLFieldType(Field elem);
/** /**
* Check if the field is manage by the local add-on * Check if the field is manage by the local add-on
* @param elem Field to inspect. * @param elem Field to inspect.
@ -21,4 +27,17 @@ public interface SqlWrapperAddOn {
*/ */
boolean isCompatibleField(Field elem); boolean isCompatibleField(Field elem);
int insertData(PreparedStatement ps, Object data, int iii) throws SQLException;
// External mean that the type of the object is absolutely not obvious...
boolean isExternal();
int generateQuerry(String tableName, Field elem, StringBuilder querry, String name, List<StateLoad> autoClasify);
int fillFromQuerry(ResultSet rs, Field elem, Object data, int count) throws SQLException, IllegalArgumentException, IllegalAccessException;
boolean canUpdate();
void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List<String> ListOtherTables, boolean createIfNotExist, boolean createDrop, int fieldId) throws Exception;
} }

View File

@ -0,0 +1,5 @@
package org.kar.archidata.sqlWrapper;
public enum StateLoad {
DISABLE, NORMAL, ARRAY
}

View File

@ -1,8 +0,0 @@
package org.kar.archidata.sqlWrapper;
public record WhereCondition(
String key,
String comparator,
Object Value) {
}

View File

@ -0,0 +1,115 @@
package org.kar.archidata.sqlWrapper.addOn;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.kar.archidata.annotation.addOn.SQLTableExternalLink;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.sqlWrapper.SqlWrapperAddOn;
import org.kar.archidata.sqlWrapper.StateLoad;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AddOnSQLTableExternalForeinKeyAsList implements SqlWrapperAddOn {
static final Logger LOGGER = LoggerFactory.getLogger(AddOnSQLTableExternalLink.class);
/**
* Convert the list if external id in a string '-' separated
* @param ids List of value (null are removed)
* @return '-' string separated
*/
protected static String getStringOfIds(List<Long> ids) {
List<Long> tmp = new ArrayList<>();
for (Long elem : ids) {
tmp.add(elem);
}
return tmp.stream().map(x -> String.valueOf(x)).collect(Collectors.joining("-"));
}
/**
* extract a list of "-" separated element from a SQL input data.
* @param rs Result Set of the BDD
* @param iii Id in the result set
* @return The list of Long value
* @throws SQLException if an error is generated in the sql request.
*/
protected static List<Long> getListOfIds(ResultSet rs, int iii) throws SQLException {
String trackString = rs.getString(iii);
if (rs.wasNull()) {
return null;
}
List<Long> out = new ArrayList<>();
String[] elements = trackString.split("-");
for (String elem : elements) {
Long tmp = Long.parseLong(elem);
out.add(tmp);
}
return out;
}
@Override
public Class<?> getAnnotationClass() {
return SQLTableExternalLink.class;
}
public String getSQLFieldType(Field elem) {
return "STRING";
}
public boolean isCompatibleField(Field elem) {
SQLTableExternalLink decorators = elem.getDeclaredAnnotation(SQLTableExternalLink.class);
return decorators != null;
}
public int insertData(PreparedStatement ps, Object data, int iii) throws SQLException {
if (data == null) {
ps.setNull(iii++, Types.BIGINT);
} else {
@SuppressWarnings("unchecked")
String dataTmp = getStringOfIds((List<Long>) data);
ps.setString(iii++, dataTmp);
}
return iii++;
}
@Override
public boolean isExternal() {
// TODO Auto-generated method stub
return false;
}
@Override
public int generateQuerry(String tableName, Field elem, StringBuilder querry, String name, List<StateLoad> autoClasify) {
autoClasify.add(StateLoad.ARRAY);
querry.append(" ");
querry.append(tableName);
querry.append(".");
querry.append(name);
return 1;
}
@Override
public int fillFromQuerry(ResultSet rs, Field elem, Object data, int count) throws SQLException, IllegalArgumentException, IllegalAccessException {
List<Long> idList = getListOfIds(rs, count);
elem.set(data, idList);
return 1;
}
@Override
public boolean canUpdate() {
return true;
}
@Override
public void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List<String> ListOtherTables, boolean createIfNotExist, boolean createDrop, int fieldId) throws Exception {
// TODO Auto-generated method stub
SqlWrapper.createTablesSpecificType(tableName, elem, mainTableBuilder, ListOtherTables, createIfNotExist, createDrop, fieldId, String.class);
}
}

View File

@ -0,0 +1,265 @@
package org.kar.archidata.sqlWrapper.addOn;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.kar.archidata.GlobalConfiguration;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.addOn.SQLTableExternalLink;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.sqlWrapper.SqlWrapper.ExceptionDBInterface;
import org.kar.archidata.sqlWrapper.SqlWrapperAddOn;
import org.kar.archidata.sqlWrapper.StateLoad;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AddOnSQLTableExternalLink implements SqlWrapperAddOn {
static final Logger LOGGER = LoggerFactory.getLogger(AddOnSQLTableExternalLink.class);
/**
* Convert the list if external id in a string '-' separated
* @param ids List of value (null are removed)
* @return '-' string separated
*/
protected static String getStringOfIds(final List<Long> ids) {
final List<Long> tmp = new ArrayList<>(ids);
return tmp.stream().map(String::valueOf).collect(Collectors.joining("-"));
}
/**
* extract a list of "-" separated element from a SQL input data.
* @param rs Result Set of the BDD
* @param iii Id in the result set
* @return The list of Long value
* @throws SQLException if an error is generated in the sql request.
*/
protected static List<Long> getListOfIds(final ResultSet rs, final int iii) throws SQLException {
final String trackString = rs.getString(iii);
if (rs.wasNull()) {
return null;
}
final List<Long> out = new ArrayList<>();
final String[] elements = trackString.split("-");
for (final String elem : elements) {
final Long tmp = Long.parseLong(elem);
out.add(tmp);
}
return out;
}
@Override
public Class<?> getAnnotationClass() {
return SQLTableExternalLink.class;
}
@Override
public String getSQLFieldType(final Field elem) {
return "STRING";
}
@Override
public boolean isCompatibleField(final Field elem) {
final SQLTableExternalLink decorators = elem.getDeclaredAnnotation(SQLTableExternalLink.class);
return decorators != null;
}
@Override
public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException {
if (data == null) {
ps.setNull(iii++, Types.BIGINT);
} else {
// TODO: we must check if the model of data in a list of Long ... !!!!
@SuppressWarnings("unchecked")
final String dataTmp = getStringOfIds((List<Long>) data);
ps.setString(iii++, dataTmp);
}
return iii++;
}
@Override
public boolean isExternal() {
// TODO Auto-generated method stub
return false;
}
@Override
public int generateQuerry(final String tableName, final Field elem, final StringBuilder querry, final String name, final List<StateLoad> autoClasify) {
autoClasify.add(StateLoad.ARRAY);
String localName = name;
if (name.endsWith("s")) {
localName = name.substring(0, name.length() - 1);
}
final String tmpVariable = "tmp_" + Integer.toString(autoClasify.size());
querry.append(" (SELECT GROUP_CONCAT(");
querry.append(tmpVariable);
querry.append(".");
querry.append(localName);
querry.append("_id SEPARATOR '-') FROM ");
querry.append(tableName);
querry.append("_link_");
querry.append(localName);
querry.append(" ");
querry.append(tmpVariable);
querry.append(" WHERE ");
querry.append(tmpVariable);
querry.append(".deleted = false AND ");
querry.append(tableName);
querry.append(".id = ");
querry.append(tmpVariable);
querry.append(".");
querry.append(tableName);
querry.append("_id GROUP BY ");
querry.append(tmpVariable);
querry.append(".");
querry.append(tableName);
querry.append("_id ) AS ");
querry.append(name);
querry.append(" ");
/*
" (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
" FROM cover_link_node tmp" +
" WHERE tmp.deleted = false" +
" AND node.id = tmp.node_id" +
" GROUP BY tmp.node_id) AS covers" +
*/
return 1;
}
@Override
public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count) throws SQLException, IllegalArgumentException, IllegalAccessException {
throw new IllegalAccessException("This Add-on has not the capability to insert data directly in DB");
}
@Override
public boolean canUpdate() {
return false;
}
public static void addLink(final Class<?> clazz, final long localKey, final String table, final long remoteKey) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
long uniqueSQLID = -1;
// real add in the BDD:
try {
// prepare the request:
final String querry = "INSERT INTO " + tableName + "_link_" + table + " (create_date, modify_date, " + tableName + "_id, " + table + "_id)" + " VALUES (" + SqlWrapper.getDBNow() + ", "
+ SqlWrapper.getDBNow() + ", ?, ?)";
final PreparedStatement ps = entry.connection.prepareStatement(querry, Statement.RETURN_GENERATED_KEYS);
int iii = 1;
ps.setLong(iii++, localKey);
ps.setLong(iii++, remoteKey);
// execute the request
final int affectedRows = ps.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating data failed, no rows affected.");
}
// retrieve uid inserted
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
uniqueSQLID = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating user failed, no ID obtained (1).");
}
} catch (final Exception ex) {
LOGGER.debug("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating user failed, no ID obtained (2).");
}
} catch (final SQLException ex) {
ex.printStackTrace();
throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
} finally {
entry.close();
entry = null;
}
}
public static void removeLink(final Class<?> clazz, final long localKey, final String table, final long remoteKey) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz);
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
final String querry = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + SqlWrapper.getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table
+ "_id` = ?";
try {
final PreparedStatement ps = entry.connection.prepareStatement(querry);
int iii = 1;
ps.setLong(iii++, localKey);
ps.setLong(iii++, remoteKey);
ps.executeUpdate();
} catch (final SQLException ex) {
ex.printStackTrace();
throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
} finally {
entry.close();
entry = null;
}
}
@Override
public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> ListOtherTables, final boolean createIfNotExist,
final boolean createDrop, final int fieldId) throws Exception {
final String name = elem.getName();
String localName = name;
if (name.endsWith("s")) {
localName = name.substring(0, name.length() - 1);
}
if (createIfNotExist && createDrop) {
final StringBuilder tableTmp = new StringBuilder();
tableTmp.append("DROP TABLE IF EXISTS `");
tableTmp.append(tableName);
tableTmp.append("_link_");
tableTmp.append(localName);
tableTmp.append("`;");
ListOtherTables.add(tableTmp.toString());
}
final StringBuilder otherTable = new StringBuilder();
otherTable.append("CREATE TABLE `");
otherTable.append(tableName);
otherTable.append("_link_");
otherTable.append(localName);
otherTable.append("`(\n");
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
otherTable.append("\t\t`id` bigint NOT NULL AUTO_INCREMENT,\n");
otherTable.append("\t\t`deleted` tinyint(1) NOT NULL DEFAULT '0',\n");
otherTable.append("\t\t`create_date` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
otherTable.append("\t\t`modify_date` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
} else {
otherTable.append("\t\t`id` INTEGER PRIMARY KEY AUTOINCREMENT,\n");
otherTable.append("\t\t`deleted` INTEGER NOT NULL DEFAULT '0',\n");
otherTable.append("\t\t`create_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
otherTable.append("\t\t`modify_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
}
otherTable.append("\t\t`");
otherTable.append(tableName);
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
otherTable.append("_id` bigint NOT NULL,\n");
} else {
otherTable.append("_id` INTEGER NOT NULL,\n");
}
otherTable.append("\t\t`");
otherTable.append(localName);
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
otherTable.append("_id` bigint NOT NULL\n");
} else {
otherTable.append("_id` INTEGER NOT NULL\n");
}
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
otherTable.append("\t, PRIMARY KEY (`id`)\n");
}
otherTable.append("\t)");
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
otherTable.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;\n\n");
}
otherTable.append(";");
ListOtherTables.add(otherTable.toString());
}
}

View File

@ -1,21 +0,0 @@
package org.kar.archidata.sqlWrapper.addOn;
import java.lang.reflect.Field;
import org.kar.archidata.annotation.SQLTableLinkGeneric;
import org.kar.archidata.sqlWrapper.SqlWrapperAddOn;
public class ExternalLink implements SqlWrapperAddOn {
@Override
public Class<?> getAnnotationClass() {
return SQLTableLinkGeneric.class;
}
public String getSQLFieldType(Field elem) {
return "STRING";
}
public boolean isCompatibleField(Field elem) {
SQLTableLinkGeneric decorators = elem.getDeclaredAnnotation(SQLTableLinkGeneric.class);
return decorators != null;
}
}

View File

@ -76,6 +76,7 @@ public class ConfigBaseVariable {
} }
return Boolean.parseBoolean(dbKeepConnected); return Boolean.parseBoolean(dbKeepConnected);
} }
public static String getlocalAddress() { public static String getlocalAddress() {
if (apiAdress == null) { if (apiAdress == null) {
return "http://0.0.0.0:80/api/"; return "http://0.0.0.0:80/api/";
@ -86,6 +87,7 @@ public class ConfigBaseVariable {
public static String getSSOAddress() { public static String getSSOAddress() {
return ssoAdress; return ssoAdress;
} }
public static String ssoToken() { public static String ssoToken() {
return ssoToken; return ssoToken;
} }

View File

@ -11,17 +11,21 @@ import java.nio.file.StandardCopyOption;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List;
import jakarta.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.kar.archidata.model.Data; import org.kar.archidata.model.Data;
import org.kar.archidata.sqlWrapper.QuerryAnd;
import org.kar.archidata.sqlWrapper.QuerryCondition;
import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalLink;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.ws.rs.core.Response;
public class DataTools { public class DataTools {
static final Logger logger = LoggerFactory.getLogger(DataTools.class); private final static Logger LOGGER = LoggerFactory.getLogger(DataTools.class);
public final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks public final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
public final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks public final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
@ -32,7 +36,7 @@ public class DataTools {
public static void createFolder(String path) throws IOException { public static void createFolder(String path) throws IOException {
if (!Files.exists(java.nio.file.Path.of(path))) { if (!Files.exists(java.nio.file.Path.of(path))) {
logger.info("Create folder: " + path); LOGGER.info("Create folder: " + path);
Files.createDirectories(java.nio.file.Path.of(path)); Files.createDirectories(java.nio.file.Path.of(path));
} }
} }
@ -40,6 +44,7 @@ public class DataTools {
public static long getTmpDataId() { public static long getTmpDataId() {
return tmpFolderId++; return tmpFolderId++;
} }
public static String getTmpFileInData(long tmpFolderId) { public static String getTmpFileInData(long tmpFolderId) {
String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId; String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
try { try {
@ -72,7 +77,7 @@ public class DataTools {
public static Data getWithSha512(String sha512) { public static Data getWithSha512(String sha512) {
try { try {
return SqlWrapper.getWhere(Data.class, "sha512", "=", sha512); return SqlWrapper.getWhere(Data.class, new QuerryCondition("sha512", "=", sha512));
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@ -82,7 +87,7 @@ public class DataTools {
public static Data getWithId(long id) { public static Data getWithId(long id) {
try { try {
return SqlWrapper.getWhere(Data.class, "deleted", "=", false, "id", "=", id); return SqlWrapper.getWhere(Data.class, new QuerryAnd(List.of(new QuerryCondition("deleted", "=", false), new QuerryCondition("id", "=", id))));
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@ -119,7 +124,8 @@ public class DataTools {
} }
String tmpPath = getTmpFileInData(tmpUID); String tmpPath = getTmpFileInData(tmpUID);
long fileSize = Files.size(Paths.get(tmpPath)); long fileSize = Files.size(Paths.get(tmpPath));
Data out = new Data();; Data out = new Data();
;
try { try {
out.sha512 = sha512; out.sha512 = sha512;
out.mimeType = mimeType; out.mimeType = mimeType;
@ -135,11 +141,11 @@ public class DataTools {
} }
String mediaPath = getFileData(out.id); String mediaPath = getFileData(out.id);
logger.info("src = {}", tmpPath); LOGGER.info("src = {}", tmpPath);
logger.info("dst = {}", mediaPath); LOGGER.info("dst = {}", mediaPath);
Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE); Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
logger.info("Move done"); LOGGER.info("Move done");
// all is done the file is correctly installed... // all is done the file is correctly installed...
return out; return out;
} }
@ -163,7 +169,7 @@ public class DataTools {
try { try {
Files.delete(Paths.get(filepath)); Files.delete(Paths.get(filepath));
} catch (IOException e) { } catch (IOException e) {
logger.info("can not delete temporary file : {}", Paths.get(filepath)); LOGGER.info("can not delete temporary file : {}", Paths.get(filepath));
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -173,8 +179,7 @@ public class DataTools {
public static String saveFile(InputStream uploadedInputStream, String serverLocation) { public static String saveFile(InputStream uploadedInputStream, String serverLocation) {
String out = ""; String out = "";
try { try {
OutputStream outpuStream = new FileOutputStream(new File( OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
serverLocation));
int read = 0; int read = 0;
byte[] bytes = new byte[CHUNK_SIZE_IN]; byte[] bytes = new byte[CHUNK_SIZE_IN];
MessageDigest md = MessageDigest.getInstance("SHA-512"); MessageDigest md = MessageDigest.getInstance("SHA-512");
@ -185,7 +190,7 @@ public class DataTools {
md.update(bytes, 0, read); md.update(bytes, 0, read);
outpuStream.write(bytes, 0, read); outpuStream.write(bytes, 0, read);
} }
logger.info("Flush input stream ... {}", serverLocation); LOGGER.info("Flush input stream ... {}", serverLocation);
outpuStream.flush(); outpuStream.flush();
outpuStream.close(); outpuStream.close();
// create the end of sha512 // create the end of sha512
@ -194,10 +199,10 @@ public class DataTools {
out = bytesToHex(sha512Digest); out = bytesToHex(sha512Digest);
uploadedInputStream.close(); uploadedInputStream.close();
} catch (IOException ex) { } catch (IOException ex) {
logger.error("Can not write in temporary file ... "); LOGGER.error("Can not write in temporary file ... ");
ex.printStackTrace(); ex.printStackTrace();
} catch (NoSuchAlgorithmException ex) { } catch (NoSuchAlgorithmException ex) {
logger.error("Can not find sha512 algorithms"); LOGGER.error("Can not find sha512 algorithms");
ex.printStackTrace(); ex.printStackTrace();
} }
return out; return out;
@ -236,22 +241,17 @@ public class DataTools {
return data; return data;
} }
public static <T> Response uploadCover(Class<T> clazz, public static <T> Response uploadCover(Class<T> clazz, Long id, String fileName, InputStream fileInputStream, FormDataContentDisposition fileMetaData) {
Long id,
String fileName,
InputStream fileInputStream,
FormDataContentDisposition fileMetaData
) {
try { try {
// correct input string stream : // correct input string stream :
fileName = multipartCorrection(fileName); fileName = multipartCorrection(fileName);
//public NodeSmall uploadFile(final FormDataMultiPart form) { //public NodeSmall uploadFile(final FormDataMultiPart form) {
logger.info("Upload media file: {}", fileMetaData); LOGGER.info("Upload media file: {}", fileMetaData);
logger.info(" - id: {}", id); LOGGER.info(" - id: {}", id);
logger.info(" - file_name: ", fileName); LOGGER.info(" - file_name: ", fileName);
logger.info(" - fileInputStream: {}", fileInputStream); LOGGER.info(" - fileInputStream: {}", fileInputStream);
logger.info(" - fileMetaData: {}", fileMetaData); LOGGER.info(" - fileMetaData: {}", fileMetaData);
T media = SqlWrapper.get(clazz, id); T media = SqlWrapper.get(clazz, id);
if (media == null) { if (media == null) {
return Response.notModified("Media Id does not exist or removed...").build(); return Response.notModified("Media Id does not exist or removed...").build();
@ -261,7 +261,7 @@ public class DataTools {
String sha512 = saveTemporaryFile(fileInputStream, tmpUID); String sha512 = saveTemporaryFile(fileInputStream, tmpUID);
Data data = getWithSha512(sha512); Data data = getWithSha512(sha512);
if (data == null) { if (data == null) {
logger.info("Need to add the data in the BDD ... "); LOGGER.info("Need to add the data in the BDD ... ");
try { try {
data = createNewData(tmpUID, fileName, sha512); data = createNewData(tmpUID, fileName, sha512);
} catch (IOException ex) { } catch (IOException ex) {
@ -274,15 +274,15 @@ public class DataTools {
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 == true) {
logger.error("Data already exist but deleted"); LOGGER.error("Data already exist but deleted");
undelete(data.id); undelete(data.id);
data.deleted = false; data.deleted = false;
} else { } else {
logger.error("Data already exist ... all good"); LOGGER.error("Data already exist ... all good");
} }
// Fist step: retrieve all the Id of each parents:... // Fist step: retrieve all the Id of each parents:...
logger.info("Find typeNode"); LOGGER.info("Find typeNode");
SqlWrapper.addLink(clazz, id, "cover", data.id); AddOnSQLTableExternalLink.addLink(clazz, id, "cover", data.id);
return Response.ok(SqlWrapper.get(clazz, id)).build(); return Response.ok(SqlWrapper.get(clazz, id)).build();
} catch (Exception ex) { } catch (Exception ex) {
System.out.println("Cat ann unexpected error ... "); System.out.println("Cat ann unexpected error ... ");

View File

@ -39,9 +39,10 @@ public class JWTWrapper {
public PublicKey(String key) { public PublicKey(String key) {
this.key = key; this.key = key;
} }
public PublicKey() {
} public PublicKey() {}
} }
public static void initLocalTokenRemote(String ssoUri, String application) throws IOException, ParseException { public static void initLocalTokenRemote(String ssoUri, String application) throws IOException, ParseException {
// check Token: // check Token:
URL obj = new URL(ssoUri + "public_key"); URL obj = new URL(ssoUri + "public_key");
@ -111,12 +112,14 @@ public class JWTWrapper {
} }
} }
public static String getPublicKeyJson() { public static String getPublicKeyJson() {
if (rsaPublicJWK == null) { if (rsaPublicJWK == null) {
return null; return null;
} }
return rsaPublicJWK.toJSONString(); return rsaPublicJWK.toJSONString();
} }
public static java.security.interfaces.RSAPublicKey getPublicKeyJava() throws JOSEException { public static java.security.interfaces.RSAPublicKey getPublicKeyJava() throws JOSEException {
if (rsaPublicJWK == null) { if (rsaPublicJWK == null) {
return null; return null;
@ -154,12 +157,7 @@ public class JWTWrapper {
Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */); Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */);
logger.warn("expiration= {}", expiration); logger.warn("expiration= {}", expiration);
JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder() JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID)).claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
.subject(Long.toString(userID))
.claim("login", userLogin)
.claim("application", application)
.issuer(isuer)
.issueTime(now)
.expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning .expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning
// add right if needed: // add right if needed:
if (rights != null && !rights.isEmpty()) { if (rights != null && !rights.isEmpty()) {

View File

@ -1,6 +1,5 @@
package org.kar.archidata.util; package org.kar.archidata.util;
public class PublicKey { public class PublicKey {
public String key; public String key;

View File

@ -31,6 +31,7 @@ public class RESTApi {
public void setToken(String token) { public void setToken(String token) {
this.token = token; this.token = token;
} }
public <T> List<T> gets(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException { public <T> List<T> gets(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
@ -47,6 +48,7 @@ public class RESTApi {
List<T> out = mapper.readValue(httpResponse.body(), new TypeReference<List<T>>() {}); List<T> out = mapper.readValue(httpResponse.body(), new TypeReference<List<T>>() {});
return out; return out;
} }
public <T> T get(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException { public <T> T get(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
@ -69,6 +71,7 @@ public class RESTApi {
T out = mapper.readValue(httpResponse.body(), clazz); T out = mapper.readValue(httpResponse.body(), clazz);
return out; return out;
} }
public <T, U> T post(Class<T> clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException { public <T, U> T post(Class<T> clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
@ -92,6 +95,7 @@ public class RESTApi {
T out = mapper.readValue(httpResponse.body(), clazz); T out = mapper.readValue(httpResponse.body(), clazz);
return out; return out;
} }
public <T> T postMap(Class<T> clazz, String urlOffset, Map<String, Object> data) throws RESTErrorResponseExeption, IOException, InterruptedException { public <T> T postMap(Class<T> clazz, String urlOffset, Map<String, Object> data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
@ -113,6 +117,7 @@ public class RESTApi {
T out = mapper.readValue(httpResponse.body(), clazz); T out = mapper.readValue(httpResponse.body(), clazz);
return out; return out;
} }
public <T, U> T put(Class<T> clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException { public <T, U> T put(Class<T> clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
@ -134,6 +139,7 @@ public class RESTApi {
T out = mapper.readValue(httpResponse.body(), clazz); T out = mapper.readValue(httpResponse.body(), clazz);
return out; return out;
} }
public <T> T putMap(Class<T> clazz, String urlOffset, Map<String, Object> data) throws RESTErrorResponseExeption, IOException, InterruptedException { public <T> T putMap(Class<T> clazz, String urlOffset, Map<String, Object> data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
@ -155,6 +161,7 @@ public class RESTApi {
T out = mapper.readValue(httpResponse.body(), clazz); T out = mapper.readValue(httpResponse.body(), clazz);
return out; return out;
} }
public <T, U> T delete(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException { public <T, U> T delete(Class<T> clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();

View File

@ -0,0 +1,44 @@
package test.kar.archidata;
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.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.util.RESTApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestBase {
final static Logger logger = LoggerFactory.getLogger(TestBase.class);
static RESTApi api = null;
@BeforeAll
public static void configureWebServer() throws Exception {
logger.info("Create DB");
final String dbName = "sdfsdfsdfsfsdfsfsfsfsdfsdfsd";
boolean data = SqlWrapper.isDBExist(dbName);
logger.error("exist: {}", data);
data = SqlWrapper.createDB(dbName);
logger.error("create: {}", data);
data = SqlWrapper.isDBExist(dbName);
logger.error("exist: {}", data);
}
@AfterAll
public static void stopWebServer() throws InterruptedException {
logger.info("Kill the web server");
// TODO: do it better...
}
@Order(1)
@Test
public void checkSimpleTestError() throws Exception {
Assertions.assertEquals("lkjlkjlkjlk", "alive and kicking");
}
}