This commit is contained in:
jeffcheasey88 2023-09-08 14:34:44 +02:00
parent 8dbb5e3474
commit a06eb168e7
3 changed files with 143 additions and 26 deletions

View file

@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteExtracter;
import dev.peerat.backend.model.Completion; import dev.peerat.backend.model.Completion;
import dev.peerat.backend.model.Group; import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser; import dev.peerat.backend.model.PeerAtUser;
@ -19,6 +20,7 @@ import dev.peerat.backend.routes.PlayerDetails;
import dev.peerat.backend.routes.PuzzleElement; import dev.peerat.backend.routes.PuzzleElement;
import dev.peerat.backend.routes.PuzzleResponse; import dev.peerat.backend.routes.PuzzleResponse;
import dev.peerat.backend.routes.Result; import dev.peerat.backend.routes.Result;
import dev.peerat.backend.routes.Swagger;
import dev.peerat.backend.routes.admins.DynamicLogs; import dev.peerat.backend.routes.admins.DynamicLogs;
import dev.peerat.backend.routes.groups.GroupCreate; import dev.peerat.backend.routes.groups.GroupCreate;
import dev.peerat.backend.routes.groups.GroupJoin; import dev.peerat.backend.routes.groups.GroupJoin;
@ -80,9 +82,6 @@ public class Main{
initRoutes(router, repo, config); initRoutes(router, repo, config);
// RouteExtracter extracter = new RouteExtracter(router);
// extracter.extract();
if(config.useSsl()) router.configureSSL(config.getSslKeystore(), config.getSslKeystorePasswd()); if(config.useSsl()) router.configureSSL(config.getSslKeystore(), config.getSslKeystorePasswd());
router.listen(config.getTcpPort(), config.useSsl()); router.listen(config.getTcpPort(), config.useSsl());
} }
@ -117,7 +116,9 @@ public class Main{
register(new GroupCreate(repo, groupLock, config.getGroupJoinMinutes())). register(new GroupCreate(repo, groupLock, config.getGroupJoinMinutes())).
register(new GroupList(repo)). register(new GroupList(repo)).
register(new GroupJoin(repo, config.getGroupJoinMinutes(), config.getGroupQuitMinutes(), leaderboard)). register(new GroupJoin(repo, config.getGroupJoinMinutes(), config.getGroupQuitMinutes(), leaderboard)).
register(new GroupQuit(repo, config.getGroupJoinMinutes(), leaderboard)); register(new GroupQuit(repo, config.getGroupJoinMinutes(), leaderboard))
.register(new Swagger(new RouteExtracter(router),config.getTokenIssuer()));
// Bot bot = new Bot(config, repo, groupLock); // Bot bot = new Bot(config, repo, groupLock);
// bot.start(); // bot.start();

View file

@ -2,48 +2,131 @@ package dev.peerat.backend.bonus.extract;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.ArrayList;
import java.util.Map.Entry; import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.framework.RequestType; import dev.peerat.framework.RequestType;
import dev.peerat.framework.Response; import dev.peerat.framework.Response;
import dev.peerat.framework.Route; import dev.peerat.framework.Route;
import dev.peerat.framework.RouteMapper;
import dev.peerat.framework.Router; import dev.peerat.framework.Router;
//A noter que le but est d'extraire des informations sans modifier le code source,
//comme les tests unitaire, ici je veux générer un élément textuel qui me donnera l'état des routes,
//je ne vais donc pas modifier la classe router pour donner un accès au route.
public class RouteExtracter { public class RouteExtracter {
private Router router; private Router<PeerAtUser> router;
public RouteExtracter(Router router){ public RouteExtracter(Router<PeerAtUser> router){
this.router = router; this.router = router;
} }
public void extract() throws Exception{ public void extract() throws Exception{
Field field = Router.class.getDeclaredField("responses"); RouteMapper[] mappers = getField(Router.class, router, "mappers");
field.setAccessible(true); for(RequestType type : RequestType.values()){
Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router); RouteMapper mapper = mappers[type.ordinal()];
for(Entry<RequestType, Map<Response, Route>> types : responses.entrySet()){ Response[] responses = getField(RouteMapper.class, mapper, "responses");
for(Entry<Response, Route> routes : types.getValue().entrySet()){ Route[] routes = getField(RouteMapper.class, mapper, "routes");
System.out.println("["+types.getKey()+"] ("+routes.getValue().needLogin()+") "+routes.getValue().path()); synchronized (responses){
for(int i = 0; i < responses.length; i++){
Route route = routes[i];
System.out.println("["+type+"] ("+route.needLogin()+") "+route.path());
}
} }
} }
} }
public void extractDoc() throws Exception{ public void extractDoc() throws Exception{
Field field = Router.class.getDeclaredField("responses"); RouteMapper[] mappers = getField(Router.class, router, "mappers");
field.setAccessible(true); for(RequestType type : RequestType.values()){
Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router); RouteMapper mapper = mappers[type.ordinal()];
for(Map<Response, Route> route : responses.values()){ Response[] responses = getField(RouteMapper.class, mapper, "responses");
for(Response response : route.keySet()){ synchronized (responses){
Method method = response.getClass().getDeclaredMethod("exec", for(int i = 0; i < responses.length; i++){
Response.class.getDeclaredMethods()[0].getParameterTypes()); Response response = responses[i];
for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){ Method method = response.getClass().getDeclaredMethod("exec",
System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription()); Response.class.getDeclaredMethods()[0].getParameterTypes());
for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){
System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription());
}
} }
} }
} }
} }
public JSONObject swagger(String host) throws Exception{
JSONObject result = new JSONObject();
result.put("swagger","2.0");
JSONObject info = new JSONObject();
info.put("title", "Peer-at-code backend api routes");
info.put("description", "Using Peer-at Code Framework");
result.put("info", info);
result.put("host", host);
result.put("basePath","/");
List<Response> routes = new ArrayList<>();
RouteMapper[] mappers = getField(Router.class, router, "mappers");
for(RequestType type : RequestType.values()){
RouteMapper mapper = mappers[type.ordinal()];
Response[] responses = getField(RouteMapper.class, mapper, "responses");
synchronized (responses){
routes.addAll(Arrays.asList(responses));
}
}
Set<String> packages = new HashSet<>();
for(Response response : routes){
String name = response.getClass().getPackage().getName();
name = name.substring(name.lastIndexOf('.')+1, name.length());
packages.add(name);
}
JSONArray tags = new JSONArray();
for(String tag : packages){
JSONObject current = new JSONObject();
current.put("name", tag);
tags.add(current);
}
result.put("tags", tags);
JSONArray schemes = new JSONArray();
schemes.add("https");
result.put("schemes", schemes);
JSONObject paths = new JSONObject();
for(Response response : routes){
Method method = response.getClass().getDeclaredMethod("exec",
Response.class.getDeclaredMethods()[0].getParameterTypes());
Route route = method.getDeclaredAnnotation(Route.class);
RouteDoc[] docs = method.getDeclaredAnnotationsByType(RouteDoc.class);
if(docs.length < 1) continue;
RouteDoc base = docs[0];
JSONObject current = new JSONObject();
JSONObject data = new JSONObject();
JSONArray tag = new JSONArray();
String pack = response.getClass().getPackage().getName();
pack = pack.substring(pack.lastIndexOf('.')+1, pack.length());
tag.add(pack);
data.put("tags", tag);
current.put(route.type().toString().toLowerCase(), data);
paths.put(base.path(), current);
}
result.put("paths", paths);
return result;
}
private <E> E getField(Class<?> clazz, Object instance, String name) throws Exception{
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return (E) field.get(instance);
}
} }

View file

@ -0,0 +1,33 @@
package dev.peerat.backend.routes;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteExtracter;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
public class Swagger implements Response{
private String json;
public Swagger(RouteExtracter extracter, String host){
try{
this.json = extracter.swagger(host).toJSONString();
}catch(Exception e){
e.printStackTrace();
json = "{}";
}
}
@Route(path = "^/swagger$")
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
context.response(200);
writer.write(json);
}
}