[FEAT] add a minimum sample (Not tested)
This commit is contained in:
parent
70cbb1aae9
commit
280d86e333
126
sample/archidata/basic/WebLauncher.java
Executable file
126
sample/archidata/basic/WebLauncher.java
Executable file
@ -0,0 +1,126 @@
|
|||||||
|
package sample.archidata.basic;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.glassfish.grizzly.http.server.HttpServer;
|
||||||
|
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
||||||
|
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||||
|
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
import org.kar.archidata.GlobalConfiguration;
|
||||||
|
import org.kar.archidata.UpdateJwtPublicKey;
|
||||||
|
import org.kar.archidata.api.DataResource;
|
||||||
|
import org.kar.archidata.catcher.ExceptionCatcher;
|
||||||
|
import org.kar.archidata.catcher.FailExceptionCatcher;
|
||||||
|
import org.kar.archidata.catcher.InputExceptionCatcher;
|
||||||
|
import org.kar.archidata.catcher.SystemExceptionCatcher;
|
||||||
|
import org.kar.archidata.db.DBConfig;
|
||||||
|
import org.kar.archidata.filter.CORSFilter;
|
||||||
|
import org.kar.archidata.filter.OptionFilter;
|
||||||
|
import org.kar.archidata.migration.MigrationEngine;
|
||||||
|
import org.kar.archidata.tools.ConfigBaseVariable;
|
||||||
|
import sample.archidata.basic.api.Front;
|
||||||
|
import sample.archidata.basic.api.HealthCheck;
|
||||||
|
import sample.archidata.basic.api.MediaResource;
|
||||||
|
import sample.archidata.basic.api.SeasonResource;
|
||||||
|
import sample.archidata.basic.api.SeriesResource;
|
||||||
|
import sample.archidata.basic.api.TypeResource;
|
||||||
|
import sample.archidata.basic.api.UserMediaAdvancementResource;
|
||||||
|
import sample.archidata.basic.api.UserResource;
|
||||||
|
import sample.archidata.basic.filter.KarideoAuthenticationFilter;
|
||||||
|
import sample.archidata.basic.migration.Initialization;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
|
public class WebLauncher {
|
||||||
|
final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
|
||||||
|
public static DBConfig dbConfig;
|
||||||
|
protected UpdateJwtPublicKey keyUpdater = null;
|
||||||
|
protected HttpServer server = null;
|
||||||
|
|
||||||
|
public WebLauncher() {
|
||||||
|
ConfigBaseVariable.bdDatabase = "sample_archidata_basic";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static URI getBaseURI() {
|
||||||
|
return UriBuilder.fromUri(ConfigBaseVariable.getlocalAddress()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void migrateDB() throws Exception {
|
||||||
|
WebLauncher.LOGGER.info("Create migration engine");
|
||||||
|
final MigrationEngine migrationEngine = new MigrationEngine();
|
||||||
|
WebLauncher.LOGGER.info("Add initialization");
|
||||||
|
migrationEngine.setInit(new Initialization());
|
||||||
|
//WebLauncher.LOGGER.info("Add migration since last version");
|
||||||
|
//migrationEngine.add(new Migration20230810());
|
||||||
|
WebLauncher.LOGGER.info("Migrate the DB [START]");
|
||||||
|
migrationEngine.migrateWaitAdmin(GlobalConfiguration.dbConfig);
|
||||||
|
WebLauncher.LOGGER.info("Migrate the DB [STOP]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(final String[] args) throws Exception {
|
||||||
|
WebLauncher.LOGGER.info("[START] application wake UP");
|
||||||
|
final WebLauncher launcher = new WebLauncher();
|
||||||
|
launcher.migrateDB();
|
||||||
|
launcher.process();
|
||||||
|
WebLauncher.LOGGER.info("end-configure the server & wait finish process:");
|
||||||
|
Thread.currentThread().join();
|
||||||
|
WebLauncher.LOGGER.info("STOP the REST server");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process() throws InterruptedException {
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
// Configure resources
|
||||||
|
// ===================================================================
|
||||||
|
final ResourceConfig rc = new ResourceConfig();
|
||||||
|
|
||||||
|
// Permit to accept OPTION request
|
||||||
|
rc.register(OptionFilter.class);
|
||||||
|
// remove cors ==> not obviously needed ...
|
||||||
|
rc.register(CORSFilter.class);
|
||||||
|
// register exception catcher (this permit to format return error with a normalized JSON)
|
||||||
|
rc.register(InputExceptionCatcher.class);
|
||||||
|
rc.register(SystemExceptionCatcher.class);
|
||||||
|
rc.register(FailExceptionCatcher.class);
|
||||||
|
rc.register(ExceptionCatcher.class);
|
||||||
|
|
||||||
|
// add default resource:
|
||||||
|
rc.register(MyModelResource.class);
|
||||||
|
|
||||||
|
|
||||||
|
// add jackson to be discover when we are in stand-alone server
|
||||||
|
rc.register(JacksonFeature.class);
|
||||||
|
|
||||||
|
this.server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
|
||||||
|
final HttpServer serverLink = this.server;
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.out.println("Stopping server..");
|
||||||
|
serverLink.shutdownNow();
|
||||||
|
}
|
||||||
|
}, "shutdownHook"));
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
// run JERSEY
|
||||||
|
// ===================================================================
|
||||||
|
try {
|
||||||
|
this.server.start();
|
||||||
|
LOGGER.info("Jersey app started at {}", getBaseURI());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOGGER.error("There was an error while starting Grizzly HTTP server.");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This is used for TEST (See it later)
|
||||||
|
public void stop() {
|
||||||
|
if (this.server != null) {
|
||||||
|
this.server.shutdownNow();
|
||||||
|
this.server = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
sample/archidata/basic/WebLauncherLocal.java
Executable file
45
sample/archidata/basic/WebLauncherLocal.java
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
package sample.archidata.basic;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.kar.archidata.api.DataResource;
|
||||||
|
import org.kar.archidata.dataAccess.DataFactoryTsApi;
|
||||||
|
import org.kar.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class WebLauncherLocal extends WebLauncher {
|
||||||
|
private final static Logger LOGGER = LoggerFactory.getLogger(WebLauncherLocal.class);
|
||||||
|
|
||||||
|
private WebLauncherLocal() {}
|
||||||
|
|
||||||
|
public static void main(final String[] args) throws Exception {
|
||||||
|
final WebLauncherLocal launcher = new WebLauncherLocal();
|
||||||
|
launcher.process();
|
||||||
|
LOGGER.info("end-configure the server & wait finish process:");
|
||||||
|
Thread.currentThread().join();
|
||||||
|
LOGGER.info("STOP the REST server:");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process() throws InterruptedException {
|
||||||
|
if (true) {
|
||||||
|
// for local test:
|
||||||
|
ConfigBaseVariable.apiAddress = "http://0.0.0.0:9000/sample/api/";
|
||||||
|
ConfigBaseVariable.dbPort = "3906";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
super.migrateDB();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
while (true) {
|
||||||
|
LOGGER.error("============================================================================");
|
||||||
|
LOGGER.error("== Migration fail ==> waiting intervention of administrator...");
|
||||||
|
LOGGER.error("============================================================================");
|
||||||
|
Thread.sleep(60 * 60 * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.process();
|
||||||
|
}
|
||||||
|
}
|
79
sample/archidata/basic/api/MyModelResource.java
Normal file
79
sample/archidata/basic/api/MyModelResource.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package sample.archidata.basic.api;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
|
import org.kar.archidata.annotation.AsyncType;
|
||||||
|
import org.kar.archidata.annotation.TypeScriptProgress;
|
||||||
|
import org.kar.archidata.api.DataResource;
|
||||||
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
|
import org.kar.archidata.dataAccess.addOn.AddOnDataJson;
|
||||||
|
import org.kar.archidata.exception.FailException;
|
||||||
|
import org.kar.archidata.exception.InputException;
|
||||||
|
import org.kar.archidata.model.Data;
|
||||||
|
import org.kar.archidata.tools.DataTools;
|
||||||
|
import sample.archidata.basic.model.MyModel;
|
||||||
|
import sample.archidata.basic.model.Season;
|
||||||
|
import sample.archidata.basic.model.Series;
|
||||||
|
import sample.archidata.basic.model.Type;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.PATCH;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.MyModelType;
|
||||||
|
|
||||||
|
@Path("/media")
|
||||||
|
@Produces(MyModelType.APPLICATION_JSON)
|
||||||
|
public class MyModelResource {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@PermitAll
|
||||||
|
public List<MyModel> gets() throws Exception {
|
||||||
|
return DataAccess.gets(MyModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@PermitAll
|
||||||
|
@Consumes(MyModelType.APPLICATION_JSON)
|
||||||
|
public MyModel create(final MyModel data) throws Exception {
|
||||||
|
return DataAccess.insert(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{id}")
|
||||||
|
@PermitAll
|
||||||
|
public MyModel get(@PathParam("id") final Long id) throws Exception {
|
||||||
|
return DataAccess.get(MyModel.class, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PATCH
|
||||||
|
@Path("{id}")
|
||||||
|
@PermitAll
|
||||||
|
@Consumes(MyModelType.APPLICATION_JSON)
|
||||||
|
public MyModel patch(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
|
||||||
|
DataAccess.updateWithJson(MyModel.class, id, jsonRequest);
|
||||||
|
return DataAccess.get(MyModel.class, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{id}")
|
||||||
|
@PermitAll
|
||||||
|
public void remove(@PathParam("id") final Long id) throws Exception {
|
||||||
|
DataAccess.delete(MyModel.class, id);
|
||||||
|
}
|
||||||
|
}
|
28
sample/archidata/basic/migration/Initialization.java
Normal file
28
sample/archidata/basic/migration/Initialization.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package sample.archidata.basic.migration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.kar.archidata.migration.MigrationSqlStep;
|
||||||
|
import sample.archidata.basic.model.MyModel;
|
||||||
|
|
||||||
|
public class Initialization extends MigrationSqlStep {
|
||||||
|
public static final List<Class<?>> CLASSES_BASE = List.of(MyModel.class);
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Initialization";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateStep() throws Exception {
|
||||||
|
for(final Class<?> clazz : CLASSES_BASE) {
|
||||||
|
addClass(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
addAction("""
|
||||||
|
ALTER TABLE `MyModel` AUTO_INCREMENT = 1000;
|
||||||
|
""",
|
||||||
|
// Only MySql support this request (fail in SQLite)
|
||||||
|
"mysql");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
sample/archidata/basic/model/MyModel.java
Normal file
36
sample/archidata/basic/model/MyModel.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package sample.archidata.basic.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.kar.archidata.annotation.DataJson;
|
||||||
|
import org.kar.archidata.model.Data;
|
||||||
|
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
// needed for Swagger interface
|
||||||
|
@Entity
|
||||||
|
// Do not generate Null in Json serialization ==> prefer undefined
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class MyModel extends GenericDataSoftDelete {
|
||||||
|
// Can not be NULL and max length is 300 (note default is 255)
|
||||||
|
@Column(nullable = false, length = 300)
|
||||||
|
public String name;
|
||||||
|
// Can be null and no max length
|
||||||
|
@Column(length = 0)
|
||||||
|
public String description;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MyModel [name=" + this.name + ", description=" + this.description + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user