Compare commits
No commits in common. "d08dd3777ab823576117267d690f89bcf2f9b6d4" and "06187944918b9d29b87012f168f2101727b5badc" have entirely different histories.
d08dd3777a
...
0618794491
13 changed files with 55 additions and 204 deletions
4
pom.xml
4
pom.xml
|
@ -62,10 +62,6 @@
|
|||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-container-image-docker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-scheduler</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
|
|
|
@ -4,12 +4,23 @@ import eu.m724.mstats.api.service.PluginService;
|
|||
import io.quarkus.runtime.StartupEvent;
|
||||
import jakarta.enterprise.event.Observes;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.persistence.EntityExistsException;
|
||||
|
||||
public class Startup {
|
||||
@Inject
|
||||
PluginService pluginService;
|
||||
|
||||
public void onStartup(@Observes StartupEvent event) {
|
||||
try {
|
||||
pluginService.createPlugin(1, "Tweaks724");
|
||||
} catch (EntityExistsException e) {
|
||||
System.out.println("exists1");
|
||||
}
|
||||
|
||||
try {
|
||||
pluginService.createPlugin(2, "Giants");
|
||||
} catch (EntityExistsException e) {
|
||||
System.out.println("exists2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
package eu.m724.mstats.api.resource;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import eu.m724.mstats.api.service.AdminService;
|
||||
import eu.m724.mstats.orm.Plugin;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.persistence.EntityExistsException;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Path("/api/admin")
|
||||
@RolesAllowed("admin")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class AdminApiResource {
|
||||
@Inject
|
||||
AdminService adminService;
|
||||
|
||||
@Path("/plugin")
|
||||
@PUT
|
||||
public Response createPlugin(CreateRequest request) {
|
||||
Plugin plugin;
|
||||
Response.Status status = Response.Status.OK;
|
||||
try {
|
||||
plugin = Plugin.createPlugin(request.name);
|
||||
} catch (EntityExistsException e) {
|
||||
plugin = Plugin.find("name", request.name).firstResult();
|
||||
status = Response.Status.CONFLICT;
|
||||
}
|
||||
|
||||
var response = new CreateResponse(plugin.id, plugin.name);
|
||||
|
||||
return Response.status(status).entity(response).build();
|
||||
}
|
||||
|
||||
@Path("/plugin")
|
||||
@DELETE
|
||||
public Response deletePlugin(DeleteRequest request) {
|
||||
Plugin plugin = Plugin.findById(request.id);
|
||||
|
||||
if (plugin == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
var response = new CreateResponse(plugin.id, plugin.name);
|
||||
|
||||
adminService.deletePlugin(plugin);
|
||||
|
||||
return Response.ok(response).build();
|
||||
}
|
||||
|
||||
@Path("/plugins")
|
||||
@GET
|
||||
public Response getPlugins() {
|
||||
List<Plugin> plugins = Plugin.listAll();
|
||||
|
||||
List<CreateResponse> responses = new ArrayList<>();
|
||||
|
||||
plugins.forEach(v -> responses.add(new CreateResponse(v.id, v.name)));
|
||||
|
||||
return Response.ok(responses).build();
|
||||
}
|
||||
|
||||
static class DeleteRequest {
|
||||
@JsonProperty("id")
|
||||
public long id;
|
||||
}
|
||||
|
||||
static class CreateRequest {
|
||||
@JsonProperty("name")
|
||||
public String name;
|
||||
}
|
||||
|
||||
static class CreateResponse {
|
||||
CreateResponse(long id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
public long id;
|
||||
|
||||
@JsonProperty("name")
|
||||
public String name;
|
||||
}
|
||||
}
|
|
@ -4,10 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.m724.mstats.api.service.PluginService;
|
||||
import eu.m724.mstats.orm.Plugin;
|
||||
import eu.m724.mstats.orm.PluginVersion;
|
||||
import eu.m724.mstats.orm.Server;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
|
@ -26,7 +24,6 @@ public class PluginApiResource {
|
|||
|
||||
@Path("/{id}")
|
||||
@GET
|
||||
@Transactional
|
||||
public Response stats(Long id) {
|
||||
Plugin plugin = pluginService.getPlugin(id);
|
||||
if (plugin == null) {
|
||||
|
@ -34,21 +31,16 @@ public class PluginApiResource {
|
|||
}
|
||||
|
||||
Map<String, Integer> servers = new HashMap<>();
|
||||
Map<String, Integer> versions = new HashMap<>();
|
||||
int serversTotal = 0;
|
||||
|
||||
List<PluginVersion> pv = PluginVersion.find("plugin", plugin).list();
|
||||
for (PluginVersion v : pv) {
|
||||
int sv = 0;
|
||||
for (Server server : v.servers) {
|
||||
sv++;
|
||||
Map<String, Integer> versions = new HashMap<>();
|
||||
for (Server server : plugin.servers) {
|
||||
String pluginVersion = server.plugins.stream().filter(p -> p.plugin.equals(plugin)).findFirst().get().version;
|
||||
serversTotal++;
|
||||
versions.put(pluginVersion, versions.getOrDefault(pluginVersion, 0) + 1);
|
||||
servers.put(server.serverVersion, servers.getOrDefault(server.serverVersion, 0) + 1);
|
||||
}
|
||||
|
||||
serversTotal += sv;
|
||||
versions.put(v.version, sv);
|
||||
}
|
||||
|
||||
StatsResponse statsResponse = new StatsResponse();
|
||||
statsResponse.id = id;
|
||||
statsResponse.name = plugin.name;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package eu.m724.mstats.api.service;
|
||||
|
||||
import eu.m724.mstats.orm.Plugin;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.transaction.Transactional;
|
||||
|
||||
@ApplicationScoped
|
||||
public class AdminService {
|
||||
@Transactional
|
||||
public void deletePlugin(Plugin plugin) {
|
||||
plugin.delete();
|
||||
}
|
||||
}
|
|
@ -7,8 +7,8 @@ import jakarta.transaction.Transactional;
|
|||
@ApplicationScoped
|
||||
public class PluginService {
|
||||
@Transactional
|
||||
public Plugin createPlugin(String name) {
|
||||
return Plugin.createPlugin(name);
|
||||
public Plugin createPlugin(long id, String name) {
|
||||
return Plugin.createPlugin(id, name);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,11 +3,10 @@ package eu.m724.mstats.api.service;
|
|||
import eu.m724.mstats.api.resource.ServerApiResource;
|
||||
import eu.m724.mstats.orm.Plugin;
|
||||
import eu.m724.mstats.orm.Server;
|
||||
import io.quarkus.scheduler.Scheduled;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.transaction.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -47,18 +46,7 @@ public class ServerService {
|
|||
// TODO
|
||||
}
|
||||
|
||||
server.lastHeartbeat = LocalDateTime.now();
|
||||
server.heartbeat = Instant.now();
|
||||
server.persistAndFlush();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Scheduled(every="30m")
|
||||
public void cleanUp() {
|
||||
System.out.println("Cleanup running");
|
||||
|
||||
LocalDateTime now = LocalDateTime.now().minusHours(2);
|
||||
long deleted = Server.delete("lastHeartbeat < ?1", now);
|
||||
|
||||
System.out.printf("Deleted %d servers\n", deleted);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,7 @@ import java.util.Base64;
|
|||
public class AuthService {
|
||||
@Transactional
|
||||
Server getServerByToken(String encoded) {
|
||||
try {
|
||||
byte[] token = Base64.getDecoder().decode(encoded);
|
||||
return Server.find("token", (Object) token).firstResult();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,13 +30,6 @@ public class MyHttpAuthenticationMechanism implements HttpAuthenticationMechanis
|
|||
String serverTokenEncoded = context.request().getHeader("X-Server-Token");
|
||||
|
||||
if (serverTokenEncoded != null) {
|
||||
if (serverTokenEncoded.equals("secure admni token")) {
|
||||
return QuarkusSecurityIdentity.builder()
|
||||
.setPrincipal(new QuarkusPrincipal("Administrator"))
|
||||
.addRole("admin")
|
||||
.build();
|
||||
}
|
||||
|
||||
Server server = authService.getServerByToken(serverTokenEncoded);
|
||||
if (server != null) {
|
||||
return QuarkusSecurityIdentity.builder()
|
||||
|
|
|
@ -15,29 +15,22 @@ public class Plugin extends PanacheEntity {
|
|||
@Column(unique = true, nullable = false)
|
||||
public String name;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
public List<PluginVersion> versions = new ArrayList<>();
|
||||
@ManyToMany(fetch = FetchType.EAGER)
|
||||
public List<Server> servers = new ArrayList<>();
|
||||
|
||||
@Transactional
|
||||
public static Plugin createPlugin(String name) {
|
||||
public static Plugin createPlugin(long id, String name) {
|
||||
if (Plugin.find("name", name).firstResultOptional().isPresent()) throw new EntityExistsException();
|
||||
|
||||
Plugin plugin = new Plugin();
|
||||
if (id != -1) {
|
||||
if (Plugin.findById(id) != null) throw new EntityExistsException();
|
||||
plugin.id = id;
|
||||
}
|
||||
plugin.name = name;
|
||||
|
||||
plugin.persistAndFlush();
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public PluginVersion getVersion(String version) {
|
||||
PluginVersion pv = PluginVersion.find("plugin = ?1 and version = ?2", this, version).firstResult();
|
||||
if (pv == null) {
|
||||
pv = new PluginVersion(this, version);
|
||||
pv.persistAndFlush();
|
||||
}
|
||||
|
||||
return pv;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package eu.m724.mstats.orm;
|
||||
|
||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(
|
||||
uniqueConstraints = @UniqueConstraint(columnNames = { "plugin", "version" }),
|
||||
indexes = @Index(columnList = "plugin_id")
|
||||
)
|
||||
public class PluginVersion extends PanacheEntity {
|
||||
public PluginVersion() {}
|
||||
|
||||
public PluginVersion(Plugin plugin, String version) {
|
||||
this.plugin = plugin;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public Plugin plugin;
|
||||
|
||||
@ManyToMany
|
||||
public List<Server> servers = new ArrayList<>();
|
||||
|
||||
public String version;
|
||||
}
|
19
src/main/java/eu/m724/mstats/orm/PluginWithVersion.java
Normal file
19
src/main/java/eu/m724/mstats/orm/PluginWithVersion.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
package eu.m724.mstats.orm;
|
||||
|
||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class PluginWithVersion extends PanacheEntity {
|
||||
public PluginWithVersion() {}
|
||||
|
||||
public PluginWithVersion(Plugin plugin, String version) {
|
||||
this.plugin = plugin;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public Plugin plugin;
|
||||
|
||||
public String version;
|
||||
}
|
|
@ -3,9 +3,8 @@ package eu.m724.mstats.orm;
|
|||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
@ -20,13 +19,12 @@ public class Server extends PanacheEntity {
|
|||
@Column(nullable = false)
|
||||
public byte[] token;
|
||||
|
||||
@ManyToMany(mappedBy = "servers", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
public List<PluginVersion> plugins = new ArrayList<>();
|
||||
@ManyToMany(fetch = FetchType.EAGER)
|
||||
public List<PluginWithVersion> plugins = new ArrayList<>();
|
||||
|
||||
public String serverVersion;
|
||||
|
||||
@CreationTimestamp
|
||||
public LocalDateTime lastHeartbeat;
|
||||
public Instant heartbeat = Instant.now();
|
||||
|
||||
public String getTokenEncoded() {
|
||||
return Base64.getEncoder().encodeToString(token);
|
||||
|
@ -42,9 +40,8 @@ public class Server extends PanacheEntity {
|
|||
if (plugins.stream().anyMatch(pwv -> pwv.plugin.id == id))
|
||||
return plugin;
|
||||
|
||||
PluginVersion pluginVersion = plugin.getVersion(version);
|
||||
plugins.add(pluginVersion);
|
||||
pluginVersion.servers.add(this);
|
||||
plugins.add(new PluginWithVersion(plugin, version));
|
||||
plugin.servers.add(this);
|
||||
|
||||
this.persistAndFlush();
|
||||
return plugin;
|
||||
|
|
Loading…
Reference in a new issue