backend migrated to Java 17
This commit is contained in:
99
build.gradle
99
build.gradle
@@ -1,6 +1,7 @@
|
||||
plugins {
|
||||
alias(catalog.plugins.lombok) apply false
|
||||
alias(catalog.plugins.wildfly)
|
||||
id 'java-library'
|
||||
id 'war'
|
||||
id 'maven-publish'
|
||||
}
|
||||
@@ -8,7 +9,22 @@ plugins {
|
||||
import net.woggioni.gradle.wildfly.Deploy2WildflyTask
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'net.woggioni.gradle.lombok'
|
||||
|
||||
pluginManager.withPlugin('java-library') {
|
||||
apply plugin: 'net.woggioni.gradle.lombok'
|
||||
|
||||
lombok {
|
||||
version = catalog.versions.lombok.get()
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.release = 17
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
group = 'net.woggioni'
|
||||
version = getProperty('jpacrepo.version')
|
||||
@@ -23,24 +39,26 @@ allprojects {
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation platform(group: 'com.lys', name: 'lys-dependencies', version: getProperty('lys.version'))
|
||||
}
|
||||
configurations {
|
||||
deployableArchives {
|
||||
attributes {
|
||||
attribute(
|
||||
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
|
||||
objects.named(LibraryElements.class, LibraryElements.JAR))
|
||||
}
|
||||
|
||||
lombok {
|
||||
version = getProperty('lombok.version')
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.release = 17
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
useJUnitPlatform()
|
||||
transitive = false
|
||||
canBeConsumed = false
|
||||
visible = false
|
||||
canBeResolved = true
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
modularity.inferModulePath = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':jpacrepo-impl')
|
||||
@@ -48,19 +66,17 @@ dependencies {
|
||||
implementation catalog.jwo
|
||||
implementation catalog.slf4j.api
|
||||
|
||||
compileOnly catalog.hibernate.jpamodelgen
|
||||
compileOnly catalog.jakarta.enterprise.cdi.api
|
||||
compileOnly catalog.jakarta.servlet.api
|
||||
compileOnly catalog.jakarta.ejb.api
|
||||
compileOnly catalog.jakarta.ws.rs.api
|
||||
compileOnly catalog.jakarta.xml.bind.api
|
||||
compileOnly catalog.jakarta.enterprise.concurrent.api
|
||||
|
||||
providedCompile catalog.jakarta.persistence.api
|
||||
providedCompile catalog.jakarta.enterprise.cdi.api
|
||||
providedCompile catalog.jakarta.servlet.api
|
||||
providedCompile catalog.jakarta.ejb.api
|
||||
providedCompile catalog.jakarta.ws.rs.api
|
||||
providedCompile catalog.jakarta.xml.bind.api
|
||||
providedCompile catalog.jakarta.enterprise.concurrent.api
|
||||
|
||||
implementation catalog.commons.compress
|
||||
implementation catalog.jna
|
||||
|
||||
|
||||
testImplementation catalog.jackson.module.jakarta.xmlbind.annotations
|
||||
testImplementation catalog.jboss.ejb.client
|
||||
testImplementation catalog.weld.se.core
|
||||
@@ -69,10 +85,20 @@ dependencies {
|
||||
testImplementation catalog.resteasy.client
|
||||
testImplementation catalog.resteasy.jackson2.provider
|
||||
testImplementation catalog.jackson.datatype.jsr310
|
||||
|
||||
|
||||
testRuntimeOnly catalog.slf4j.simple
|
||||
|
||||
testImplementation catalog.junit.jupiter.api
|
||||
testImplementation catalog.junit.jupiter.params
|
||||
|
||||
testRuntimeOnly catalog.jakartaee.api
|
||||
testRuntimeOnly catalog.junit.jupiter.engine
|
||||
testRuntimeOnly group: 'org.glassfish.main.extras', name: 'glassfish-embedded-all', version: '7.0.6'
|
||||
|
||||
deployableArchives project
|
||||
deployableArchives project(':jpacrepo-impl')
|
||||
deployableArchives project(':jpacrepo-api')
|
||||
}
|
||||
|
||||
File nimDir = project.file('nim')
|
||||
@@ -83,7 +109,7 @@ Provider<Exec> nimCompileTaskProvider = tasks.register("compileNim", Exec) {
|
||||
inputs.files(project.fileTree(srcDir), project.fileTree(staticDir))
|
||||
File outputFile = new File(temporaryDir, "jpacrepo.js")
|
||||
outputs.file(outputFile)
|
||||
commandLine 'nim', 'js', "-o:$outputFile", 'src/jpacrepo.nim'
|
||||
commandLine 'nim', 'js', '-d:release', "-o:$outputFile", 'src/jpacrepo.nim'
|
||||
workingDir(nimDir)
|
||||
}
|
||||
|
||||
@@ -92,7 +118,30 @@ Provider<War> warTaskProvider = tasks.named('war', War) {
|
||||
from nimCompileTaskProvider
|
||||
}
|
||||
|
||||
tasks.named('deploy2Wildfly', Deploy2WildflyTask) {
|
||||
tasks.named('deploy2Wildfly', Deploy2WildflyTask) { d2w ->
|
||||
d2w.rpcPort = 1234
|
||||
d2w.rpcUsername = 'woggioni'
|
||||
// d2w.rpcUsername = 'admin'
|
||||
d2w.rpcPassword = '123456'
|
||||
}
|
||||
|
||||
|
||||
File warPath = tasks.named("war", War).get().archiveFile.get().getAsFile()
|
||||
tasks.named("test", Test) {
|
||||
jvmArgs = [
|
||||
'--add-opens', 'java.naming/javax.naming.spi=ALL-UNNAMED',
|
||||
'--add-opens', 'java.base/java.lang=ALL-UNNAMED',
|
||||
'--add-opens', 'java.base/java.io=ALL-UNNAMED',
|
||||
// '--add-opens', 'java.base/java.util=ALL-UNNAMED',
|
||||
// '--add-opens', 'java.management/javax.management.openmbean=ALL-UNNAMED',
|
||||
// '--add-opens', 'java.management/javax.management=ALL-UNNAMED',
|
||||
]
|
||||
// classpath = configurations.testRuntimeClasspath + sourceSets.test.output
|
||||
// File warPath = tasks.named("war", War).get().archiveFile.get().getAsFile()
|
||||
// classpath += warPath
|
||||
// classpath += tasks.named("war", War).get().outputs.files
|
||||
inputs.files(configurations.deployableArchives)
|
||||
systemProperty('jpacrepo.jar.path', configurations.deployableArchives.asPath)
|
||||
}
|
||||
|
||||
publishing {
|
||||
|
@@ -1,29 +1,3 @@
|
||||
net.woggioni.gradle.lombok.version=0.1
|
||||
net.woggioni.gradle.wildfly.version=0.1
|
||||
net.woggioni.gradle.envelope.version=1.0-SNAPSHOT
|
||||
jpacrepo.version=2023.07
|
||||
|
||||
jpacrepo.version=2.0-SNAPSHOT
|
||||
|
||||
lys.version=0.1-SNAPSHOT
|
||||
|
||||
lombok.version=1.18.22
|
||||
slf4j.version=1.7.32
|
||||
xz.version=1.9
|
||||
apache.commons.compress.version=1.21
|
||||
hibernate.version=5.6.5.Final
|
||||
jzstd.version=0.1-SNAPSHOT
|
||||
jwo.version=1.0-SNAPSHOT
|
||||
jakarta.persistence.version=3.1.0
|
||||
jakarta.inject.version=2.0.1
|
||||
jakarta.cdi.version=4.0.1
|
||||
jakarta.annotation.version=2.1.1
|
||||
jakarta.ee.version=8.0.0
|
||||
jaxb.api.version=2.3.1
|
||||
|
||||
jboss.ejb.client.version=4.0.43.Final
|
||||
log4j.version=2.17.2
|
||||
weld.version=4.0.3.Final
|
||||
h2.version=2.1.210
|
||||
resteasy.version=6.0.0.Final
|
||||
jna.version=5.10.0
|
||||
junit.jupiter.version=5.8.2
|
||||
lys.version=2023.07.20
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
6
gradlew
vendored
6
gradlew
vendored
@@ -205,6 +205,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
14
gradlew.bat
vendored
14
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,7 +25,7 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
@@ -4,8 +4,14 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
compileOnly catalog.jakarta.xml.bind.api
|
||||
compileOnly catalog.jakarta.ejb.api
|
||||
compileOnly catalog.jakarta.persistence.api
|
||||
compileOnly catalog.jakarta.inject.api
|
||||
compileOnly catalog.jakarta.ejb.api
|
||||
compileOnly catalog.jakarta.json.bind.api
|
||||
compileOnly catalog.jakarta.annotation.api
|
||||
|
||||
annotationProcessor catalog.hibernate.jpamodelgen
|
||||
|
||||
}
|
||||
|
||||
tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompile) {
|
||||
|
@@ -1,9 +1,12 @@
|
||||
module net.woggioni.jpacrepo.api {
|
||||
requires static lombok;
|
||||
requires static jakarta.xml.bind;
|
||||
requires static jakarta.ejb;
|
||||
requires static jakarta.persistence;
|
||||
requires jakarta.xml.bind;
|
||||
requires jakarta.ejb;
|
||||
requires jakarta.persistence;
|
||||
requires jakarta.annotation;
|
||||
requires jakarta.json.bind;
|
||||
|
||||
exports net.woggioni.jpacrepo.api.model;
|
||||
exports net.woggioni.jpacrepo.api.service;
|
||||
exports net.woggioni.jpacrepo.api.wire;
|
||||
}
|
@@ -3,6 +3,8 @@ package net.woggioni.jpacrepo.api.model;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum CompressionFormat {
|
||||
XZ("xz"), GZIP("gz"), Z_STANDARD("zst");
|
||||
|
@@ -1,27 +1,28 @@
|
||||
package net.woggioni.jpacrepo.api.model;
|
||||
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.json.bind.annotation.JsonbTransient;
|
||||
import jakarta.json.bind.annotation.JsonbVisibility;
|
||||
import jakarta.json.bind.config.PropertyVisibilityStrategy;
|
||||
import jakarta.persistence.Access;
|
||||
import jakarta.persistence.AccessType;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.NamedQueries;
|
||||
import jakarta.persistence.NamedQuery;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlTransient;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
@@ -38,8 +39,8 @@ import java.util.Set;
|
||||
@Index(columnList = "fileName", unique = true)
|
||||
})
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class PkgData {
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public class PkgData implements Serializable {
|
||||
|
||||
@EmbeddedId
|
||||
private PkgId id;
|
||||
@@ -50,7 +51,7 @@ public class PkgData {
|
||||
|
||||
private String url;
|
||||
|
||||
private OffsetDateTime buildDate;
|
||||
private Instant buildDate;
|
||||
|
||||
private String packager;
|
||||
|
||||
@@ -86,12 +87,14 @@ public class PkgData {
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
private Set<String> backup;
|
||||
|
||||
private OffsetDateTime updTimestamp;
|
||||
@XmlTransient
|
||||
@JsonbTransient
|
||||
private Instant updTimestamp;
|
||||
|
||||
@PreUpdate
|
||||
@PrePersist
|
||||
private void writeTimestamp() {
|
||||
updTimestamp = OffsetDateTime.now();
|
||||
updTimestamp = Instant.now();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@ import java.io.Serializable;
|
||||
@Embeddable
|
||||
@Access(AccessType.FIELD)
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public class PkgId implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
@@ -1,8 +1,7 @@
|
||||
package net.woggioni.jpacrepo.api.service;
|
||||
|
||||
import jakarta.ejb.Local;
|
||||
|
||||
|
||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
|
||||
import java.util.List;
|
||||
@@ -10,5 +9,11 @@ import java.util.List;
|
||||
@Local
|
||||
public interface PacmanServiceLocal extends PacmanServiceRemote {
|
||||
long countResults(String name, String version, String arch);
|
||||
List<PkgData> searchPackage(String name, String version, String arch, int page, int pageSize, String fileName);
|
||||
List<PkgData> searchPackage(String name,
|
||||
String version,
|
||||
String arch,
|
||||
CompressionFormat compressionFormat,
|
||||
String fileName,
|
||||
int pageNumber,
|
||||
int pageSize);
|
||||
}
|
@@ -1,9 +1,47 @@
|
||||
package net.woggioni.jpacrepo.api.service;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import jakarta.ejb.Remote;
|
||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Set;
|
||||
|
||||
@Remote
|
||||
public interface PacmanServiceRemote {
|
||||
void syncDB();
|
||||
|
||||
void deletePackage(String filename);
|
||||
|
||||
List<String> searchName(@Nonnull String name);
|
||||
|
||||
List<PkgData> searchByHash(@Nonnull String hash);
|
||||
|
||||
List<PkgData> searchByFileName(@Nonnull String fileName);
|
||||
|
||||
List<String> listFiles();
|
||||
|
||||
List<String> listHashes();
|
||||
|
||||
List<PkgId> searchPkgId(
|
||||
String name,
|
||||
String version,
|
||||
String arch,
|
||||
CompressionFormat compressionFormat);
|
||||
|
||||
@Nullable
|
||||
PkgData getPackage(PkgId pkgId);
|
||||
|
||||
@Nullable
|
||||
Long getFileSize(String fileName);
|
||||
|
||||
Set<String> missingFiles(Collection<String> fileNames);
|
||||
|
||||
NavigableMap<PkgId, PkgTuple> getPkgMap();
|
||||
}
|
@@ -1,18 +1,22 @@
|
||||
package net.woggioni.jpacrepo.service.wire;
|
||||
package net.woggioni.jpacrepo.api.wire;
|
||||
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@XmlRootElement
|
||||
@XmlRootElement(name = "packages")
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public class PkgDataList extends ArrayList<PkgData> {
|
||||
|
||||
public PkgDataList(List<PkgData> l) {
|
||||
for (PkgData el : l) add(el);
|
||||
public PkgDataList() {}
|
||||
public PkgDataList(Collection<PkgData> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
public PkgDataList(PkgData... elements) {
|
||||
@@ -20,11 +24,11 @@ public class PkgDataList extends ArrayList<PkgData> {
|
||||
}
|
||||
|
||||
@XmlElement(name = "pkgData")
|
||||
List<PkgData> getItems() {
|
||||
public List<PkgData> getItems() {
|
||||
return this;
|
||||
}
|
||||
|
||||
void setItems(List<PkgData> pkgs) {
|
||||
public void setItems(List<PkgData> pkgs) {
|
||||
this.clear();
|
||||
this.addAll(pkgs);
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package net.woggioni.jpacrepo.service.wire;
|
||||
package net.woggioni.jpacrepo.api.wire;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import lombok.Data;
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
public class PkgTuple {
|
||||
String md5sum;
|
||||
|
||||
String filename;
|
||||
String fileName;
|
||||
|
||||
long size;
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package net.woggioni.jpacrepo.service.wire;
|
||||
package net.woggioni.jpacrepo.api.wire;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
5
jpacrepo-api/src/main/resources/META-INF/beans.xml
Normal file
5
jpacrepo-api/src/main/resources/META-INF/beans.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
|
||||
version="4.0" bean-discovery-mode="annotated">
|
||||
</beans>
|
11
jpacrepo-frontend/build.gradle
Normal file
11
jpacrepo-frontend/build.gradle
Normal file
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
alias(catalog.plugins.kotlin.multiplatform)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js(IR) {
|
||||
browser {
|
||||
}
|
||||
binaries.executable()
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package net.woggioni.jpacrepo
|
||||
|
||||
import org.w3c.dom.Document
|
||||
import org.w3c.dom.Element
|
||||
|
||||
|
||||
class HtmlBuilder private constructor(private val doc : Document, val el: Element) {
|
||||
|
||||
companion object {
|
||||
fun <T> of(doc : Document, el: Element, cb : HtmlBuilder.(el : Element) -> T) : T {
|
||||
return HtmlBuilder(doc, el).cb(el)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T> dfd(
|
||||
name : String,
|
||||
attrs : Map<String, String>,
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T {
|
||||
val child = doc.createElement(name)
|
||||
for((key, value) in attrs) {
|
||||
child.setAttribute(key, value)
|
||||
}
|
||||
el.appendChild(child)
|
||||
return HtmlBuilder(doc, child).cb(child)
|
||||
}
|
||||
|
||||
fun <T> html(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("html", attrs, cb)
|
||||
fun <T> head(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("head", attrs, cb)
|
||||
fun <T> body(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("body", attrs, cb)
|
||||
|
||||
fun <T> div(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("div", attrs, cb)
|
||||
fun <T> header(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("header", attrs, cb)
|
||||
fun <T> main(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("main", attrs, cb)
|
||||
fun <T> footer(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("footer", attrs, cb)
|
||||
fun <T> a(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("a", attrs, cb)
|
||||
fun <T> meta(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("meta", attrs, cb)
|
||||
fun <T> script(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("script", attrs, cb)
|
||||
fun <T> link(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("link", attrs, cb)
|
||||
fun <T> title(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("title", attrs, cb)
|
||||
fun <T> p(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("p", attrs, cb)
|
||||
|
||||
fun <T> h1(attrs : Map<String, String> = emptyMap(),
|
||||
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("h1", attrs, cb)
|
||||
|
||||
|
||||
fun classes(vararg classes : String) {
|
||||
for(cls in classes) el.classList.add(cls)
|
||||
}
|
||||
|
||||
fun attr(key: String, value : String) {
|
||||
el.setAttribute(key, value)
|
||||
}
|
||||
|
||||
fun text(txt : String) {
|
||||
el.textContent = txt
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
package net.woggioni.jpacrepo
|
||||
|
||||
import kotlinx.browser.document
|
||||
import net.woggioni.jpacrepo.Component.container
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
|
||||
object Component {
|
||||
val container = document.getElementById("container") as HTMLElement
|
||||
|
||||
fun sayHelloViaDom() {
|
||||
container.textContent = "Hello, DOM! Kotlin is writing…"
|
||||
}
|
||||
}
|
||||
|
||||
fun main(vararg args: String) {
|
||||
// println("JavaScript generated through Kotlin")
|
||||
//
|
||||
// Component.sayHelloViaDom()
|
||||
// sayHelloViaJsConsole()
|
||||
// sayHelloViaInlinedJavaScript()
|
||||
|
||||
HtmlBuilder.of(document, document.body as HTMLElement) {
|
||||
classes("d-flex", "h-100", "text-center", "text-white", "bg-dark")
|
||||
div {
|
||||
classes("cover-container", "d-flex", "w-100", "h-100", "p-3", "mx-auto", "flex-column")
|
||||
|
||||
}
|
||||
header {
|
||||
classes("mb-auto")
|
||||
}
|
||||
main {
|
||||
classes("px-3")
|
||||
h1 {
|
||||
text("Cover your page.")
|
||||
}
|
||||
p {
|
||||
classes("lead")
|
||||
text("Cover is a one-page template for building simple and beautiful home pages. Download, edit the text, and add your own fullscreen background photo to make it your own.")
|
||||
}
|
||||
p {
|
||||
classes("lead")
|
||||
a {
|
||||
classes("btn", "btn-lg", "btn-secondary", "fw-bold", "border-white", "bg-white")
|
||||
text("Learn more")
|
||||
}
|
||||
}
|
||||
}
|
||||
footer {
|
||||
classes("mt-auto", "text-white-50")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sayHelloViaJsConsole() {
|
||||
console.log("Hello from `console.log()`!")
|
||||
}
|
||||
|
||||
private fun sayHelloViaInlinedJavaScript() {
|
||||
js("document.writeln('Hello, from inlined JavaScript in Kotlin!')")
|
||||
}
|
10
jpacrepo-frontend/src/main/resources/index.html
Normal file
10
jpacrepo-frontend/src/main/resources/index.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
||||
<script src="jpacrepo-frontend.js" defer="true"></script>
|
||||
<title>Hello World!</title>
|
||||
</html>
|
@@ -23,8 +23,6 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -110,8 +108,8 @@ public class PkgDataImpl {
|
||||
data.getId().setName(value.get(0));
|
||||
break;
|
||||
case "builddate":
|
||||
data.setBuildDate(OffsetDateTime.ofInstant(
|
||||
Instant.ofEpochSecond(Long.parseLong(value.get(0))), ZoneOffset.UTC));
|
||||
data.setBuildDate(
|
||||
Instant.ofEpochSecond(Long.parseLong(value.get(0))));
|
||||
break;
|
||||
case "license":
|
||||
data.setLicense(value.get(0));
|
||||
|
@@ -129,7 +129,7 @@ proc readTableRow(arch : string, row : Element) : JsonNode =
|
||||
let version = $row.querySelector("td:nth-child(3) button").textContent
|
||||
let filename = $row.querySelector("td:nth-child(4) button").textContent
|
||||
for candidate in pkgMap[arch][pkgname][version]:
|
||||
if filename == candidate["filename"].getStr:
|
||||
if filename == candidate["fileName"].getStr:
|
||||
return candidate
|
||||
|
||||
proc createDropdown(parent : Element, data :seq[string], onchange : proc(value : string)) =
|
||||
@@ -241,7 +241,7 @@ proc newPkgTable(parent: Element, arch: string, searchString : string, addButton
|
||||
files = f
|
||||
break
|
||||
for file in files:
|
||||
data.add(file["filename"].getStr)
|
||||
data.add(file["fileName"].getStr)
|
||||
createDropdown(elem, data, size_change_callback)
|
||||
"td":
|
||||
cb:
|
||||
@@ -309,7 +309,7 @@ htmlTreeappend document.body:
|
||||
for row in rows:
|
||||
let cbox = row.querySelector("td:first-child input")
|
||||
if cbox.checked:
|
||||
dp.addPkg(readTableRow(selectedArch, row)["filename"].getStr)
|
||||
dp.addPkg(readTableRow(selectedArch, row)["fileName"].getStr)
|
||||
oninput:
|
||||
searchString = $elem.value
|
||||
updateTable(event)
|
||||
|
@@ -1,5 +1,11 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenLocal {
|
||||
content {
|
||||
includeGroup 'net.woggioni.gradle'
|
||||
includeGroup 'net.woggioni.gradle.lombok'
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url = 'https://woggioni.net/mvn/'
|
||||
content {
|
||||
@@ -34,4 +40,5 @@ rootProject.name = 'jpacrepo'
|
||||
|
||||
include 'jpacrepo-api'
|
||||
include 'jpacrepo-impl'
|
||||
include 'jpacrepo-client'
|
||||
include 'jpacrepo-client'
|
||||
include 'jpacrepo-frontend'
|
@@ -14,4 +14,5 @@ open module net.woggioni.jpacrepo {
|
||||
requires org.slf4j;
|
||||
|
||||
requires net.woggioni.jpacrepo.api;
|
||||
requires org.apache.commons.compress;
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package net.woggioni.jpacrepo.factory;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.enterprise.inject.Produces;
|
||||
import jakarta.enterprise.inject.spi.InjectionPoint;
|
||||
import net.woggioni.jpacrepo.config.AppConfig;
|
||||
@@ -7,6 +8,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@ApplicationScoped
|
||||
public class BeanFactory {
|
||||
|
||||
@Produces
|
||||
|
@@ -8,15 +8,15 @@ import net.woggioni.jpacrepo.config.AppConfig;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
@ApplicationScoped
|
||||
public class PersistenceUnitFactory {
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
private EntityManagerFactory createEntityManagerFactory(AppConfig appConfig) {
|
||||
Properties properties = new Properties();
|
||||
properties.put("javax.persistence.schema-generation.database.action",
|
||||
properties.put("jakarta.persistence.schema-generation.database.action",
|
||||
appConfig.getInitialSchemaAction().getValue());
|
||||
properties.put("javax.persistence.jtaDataSource", appConfig.getDataSourceJndi());
|
||||
properties.put("jakarta.persistence.jtaDataSource", appConfig.getDataSourceJndi());
|
||||
return Persistence.createEntityManagerFactory("jpacrepo_pu", properties);
|
||||
}
|
||||
}
|
||||
|
@@ -5,99 +5,23 @@ import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Path;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData_;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId_;
|
||||
import net.woggioni.jwo.JWO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class QueryEngine
|
||||
{
|
||||
private String entityName;
|
||||
private String query;
|
||||
private List<String> where;
|
||||
|
||||
public QueryEngine(Class<?> cls) {
|
||||
query = String.format("SELECT e FROM %s e", cls.getSimpleName());
|
||||
this.entityName = cls.getSimpleName();
|
||||
where = new ArrayList<>();
|
||||
}
|
||||
|
||||
public QueryEngine(String entityName) {
|
||||
query = String.format("SELECT e FROM %s e", entityName);
|
||||
where = new ArrayList<>();
|
||||
}
|
||||
|
||||
public QueryEngine select(String... fields) {
|
||||
String[] strarr = new String[fields.length];
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
strarr[i] = "e." + fields[i];
|
||||
}
|
||||
query = "SELECT " + String.join(",", strarr) + " FROM " + entityName + " e";
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryEngine select() {
|
||||
query = String.format("SELECT e FROM %s e", entityName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryEngine where(String field, String operator, String value) {
|
||||
where.add(String.format("e.%s %s '%s'", field, operator, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public String build() {
|
||||
if (where.isEmpty()) {
|
||||
return query;
|
||||
} else {
|
||||
return query + " WHERE " + String.join(" AND ", where);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<PkgData> searchPackage(
|
||||
EntityManager em, String name, String version, String arch, int pageNumber, int pageSize, String fileName) {
|
||||
CriteriaBuilder builder;
|
||||
CriteriaQuery<PkgData> criteriaQuery;
|
||||
Root<PkgData> entity;
|
||||
|
||||
builder = em.getCriteriaBuilder();
|
||||
criteriaQuery = builder.createQuery(PkgData.class);
|
||||
entity = criteriaQuery.from(PkgData.class);
|
||||
Predicate finalPredicate = null, p;
|
||||
|
||||
if (name != null && !name.isEmpty()) {
|
||||
p = builder.equal(entity.get("name").get("id"), name);
|
||||
finalPredicate = p;
|
||||
}
|
||||
if (version != null && !version.isEmpty()) {
|
||||
p = builder.equal(entity.get("version"), version);
|
||||
finalPredicate = finalPredicate != null ? builder.and(finalPredicate, p) : p;
|
||||
}
|
||||
if (arch != null && !arch.isEmpty()) {
|
||||
p = builder.equal(entity.get("arch"), arch);
|
||||
finalPredicate = finalPredicate != null ? builder.and(finalPredicate, p) : p;
|
||||
}
|
||||
if (fileName != null && !fileName.isEmpty()) {
|
||||
p = builder.equal(entity.get("fileName"), fileName);
|
||||
finalPredicate = finalPredicate != null ? builder.and(finalPredicate, p) : p;
|
||||
}
|
||||
|
||||
if (finalPredicate != null) {
|
||||
criteriaQuery.select(entity).where(finalPredicate).orderBy(builder.asc(entity.get("fileName")));
|
||||
} else {
|
||||
criteriaQuery.select(entity).orderBy(builder.asc(entity.get("fileName")));
|
||||
}
|
||||
TypedQuery<PkgData> query = em.createQuery(criteriaQuery);
|
||||
if (pageNumber >= 0) {
|
||||
query.setFirstResult(pageNumber * pageSize);
|
||||
}
|
||||
if (pageSize > 0) {
|
||||
query.setMaxResults(pageSize);
|
||||
}
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
public static long countResults(EntityManager em, String name, String version, String arch) {
|
||||
CriteriaBuilder builder;
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package net.woggioni.jpacrepo.service;
|
||||
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.ejb.Asynchronous;
|
||||
import jakarta.ejb.ConcurrencyManagement;
|
||||
@@ -9,38 +11,45 @@ import jakarta.ejb.Lock;
|
||||
import jakarta.ejb.LockType;
|
||||
import jakarta.ejb.Remote;
|
||||
import jakarta.ejb.Schedule;
|
||||
import jakarta.ejb.Startup;
|
||||
import jakarta.ejb.Singleton;
|
||||
import jakarta.ejb.TransactionAttribute;
|
||||
import jakarta.ejb.TransactionAttributeType;
|
||||
import jakarta.ejb.TransactionManagement;
|
||||
import jakarta.ejb.TransactionManagementType;
|
||||
import jakarta.enterprise.concurrent.ManagedExecutorService;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||
import net.woggioni.jpacrepo.api.service.PacmanServiceLocal;
|
||||
import net.woggioni.jpacrepo.api.service.PacmanServiceRemote;
|
||||
import net.woggioni.jpacrepo.config.AppConfig;
|
||||
import net.woggioni.jpacrepo.impl.model.CompressionFormatImpl;
|
||||
import net.woggioni.jpacrepo.impl.model.PkgDataImpl;
|
||||
import net.woggioni.jpacrepo.persistence.QueryEngine;
|
||||
import net.woggioni.jpacrepo.service.jpa.Queries;
|
||||
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
||||
import net.woggioni.jpacrepo.version.PkgIdComparator;
|
||||
import net.woggioni.jwo.CollectionUtils;
|
||||
import net.woggioni.jwo.Con;
|
||||
import net.woggioni.jwo.JWO;
|
||||
import net.woggioni.jwo.Sup;
|
||||
import net.woggioni.jwo.Tuple2;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletionService;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -48,8 +57,8 @@ import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Startup
|
||||
@Singleton
|
||||
@Lock(LockType.READ)
|
||||
@TransactionManagement(TransactionManagementType.CONTAINER)
|
||||
@@ -69,10 +78,6 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||
@Resource(name = "DefaultManagedExecutorService")
|
||||
private ManagedExecutorService executor;
|
||||
|
||||
private final static String nameQuery = "SELECT pname FROM PkgName pname WHERE id = :name";
|
||||
private final static String hashQuery = "SELECT pdata FROM PkgData pdata WHERE md5sum = :md5sum";
|
||||
private final static String hashQueryCount = "SELECT count(pdata) FROM PkgData pdata WHERE md5sum = :md5sum";
|
||||
|
||||
private void deletePkgData(EntityManager em, PkgData pkgData) {
|
||||
em.remove(pkgData);
|
||||
}
|
||||
@@ -88,7 +93,7 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||
logger.info("Starting repository cleanup");
|
||||
//Removes from DB the packages that have been deleted from filesystem
|
||||
logger.info("Searching for packages that are no more in the filesystem");
|
||||
List<String> resultList = em.createQuery("SELECT p.fileName FROM PkgData p", String.class)
|
||||
List<String> resultList = Queries.listAllPackageFiles(em)
|
||||
.getResultList();
|
||||
logger.info("Got list of filenames from db");
|
||||
Set<String> knownPkg = resultList.stream().filter(fileName -> {
|
||||
@@ -96,9 +101,9 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||
boolean result = Files.exists(file);
|
||||
if (!result) {
|
||||
logger.info("Removing package {} which was not found in filesystem", file.getFileName());
|
||||
em.createQuery("SELECT p FROM PkgData p WHERE p.fileName = :fileName", PkgData.class)
|
||||
.setParameter("fileName", file.getFileName().toString())
|
||||
.getResultList().forEach(pkgData -> deletePkgData(em, pkgData));
|
||||
Queries.getPackageByFileName(em, file.getFileName().toString())
|
||||
.getResultList()
|
||||
.forEach(pkgData -> deletePkgData(em, pkgData));
|
||||
}
|
||||
return result;
|
||||
}).collect(Collectors.toUnmodifiableSet());
|
||||
@@ -106,28 +111,32 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||
CompletionService<PkgData> completionService = new ExecutorCompletionService<>(executor);
|
||||
final Set<Future<PkgData>> inProgress = new HashSet<>();
|
||||
final int maxInProgress = Runtime.getRuntime().availableProcessors() * 5;
|
||||
Con<Boolean> persistPackages = (Boolean drain) -> {
|
||||
while ((drain && inProgress.size() > 0) || inProgress.size() > maxInProgress) {
|
||||
Future<PkgData> future = completionService.poll(1, TimeUnit.SECONDS);
|
||||
inProgress.remove(future);
|
||||
PkgData pkgData;
|
||||
try {
|
||||
pkgData = future.get();
|
||||
} catch (ExecutionException ee) {
|
||||
throw ee.getCause();
|
||||
}
|
||||
persistPackage(em, pkgData);
|
||||
}
|
||||
};
|
||||
Files.list(ctx.getRepoFolder()).filter((Path file) -> {
|
||||
Sup<Stream<Path>> fileListStreamSupplier = () -> Files.list(ctx.getRepoFolder()).filter((Path file) -> {
|
||||
String name = file.getFileName().toString();
|
||||
return name.endsWith(".pkg.tar.xz") || name.endsWith(".pkg.tar.zst") || name.endsWith(".pkg.tar.gz");
|
||||
}).forEach((Con<Path>) file -> {
|
||||
});
|
||||
long[] count = new long[] {0};
|
||||
long totalPackages = fileListStreamSupplier.get().count();
|
||||
|
||||
Con<Boolean> persistPackages = (Boolean drain) -> {
|
||||
while ((drain && inProgress.size() > 0) || inProgress.size() > maxInProgress) {
|
||||
Optional.ofNullable(completionService.poll(1, TimeUnit.SECONDS))
|
||||
.ifPresent((Con<Future<PkgData>>) future -> {
|
||||
inProgress.remove(future);
|
||||
PkgData pkgData;
|
||||
try {
|
||||
pkgData = future.get();
|
||||
} catch (ExecutionException ee) {
|
||||
throw ee.getCause();
|
||||
}
|
||||
persistPackage(em, pkgData, ++count[0], totalPackages);
|
||||
});
|
||||
}
|
||||
};
|
||||
fileListStreamSupplier.get().forEach((Con<Path>) file -> {
|
||||
if (!knownPkg.contains(file.getFileName().toString()) || ((Sup<Boolean>) () -> {
|
||||
TypedQuery<Date> query = em.createQuery("SELECT p.updTimestamp FROM PkgData p WHERE filename = :filename", Date.class);
|
||||
query.setParameter("filename", file.getFileName().toString());
|
||||
Date result = query.getSingleResult();
|
||||
return Files.getLastModifiedTime(file).toMillis() > result.getTime();
|
||||
Instant result = Queries.getUpdateTimestampByFileName(em, file.getFileName().toString()).getSingleResult();
|
||||
return Files.getLastModifiedTime(file).toMillis() > result.toEpochMilli();
|
||||
}).get()) {
|
||||
inProgress.add(completionService.submit(() -> {
|
||||
try {
|
||||
@@ -150,16 +159,13 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||
}
|
||||
}
|
||||
|
||||
private void persistPackage(EntityManager em, PkgData pkgData) {
|
||||
TypedQuery<Long> hquery = em.createQuery(hashQueryCount, Long.class);
|
||||
hquery.setParameter("md5sum", pkgData.getMd5sum());
|
||||
if (hquery.getSingleResult() == 0) {
|
||||
TypedQuery<PkgData> fquery =
|
||||
em.createQuery("SELECT p FROM PkgData p WHERE p.fileName = :fileName", PkgData.class);
|
||||
fquery.setParameter("fileName", pkgData.getFileName());
|
||||
fquery.getResultList().forEach(p -> deletePkgData(em, p));
|
||||
private void persistPackage(EntityManager em, PkgData pkgData, long count, long totalPackages) {
|
||||
if (Queries.countPackagesByHash(em, pkgData.getMd5sum()).getSingleResult() == 0) {
|
||||
Queries.getPackageByFileName(em, pkgData.getFileName())
|
||||
.getResultList()
|
||||
.forEach(p -> deletePkgData(em, p));
|
||||
em.persist(pkgData);
|
||||
logger.info("Persisting package {}", pkgData.getFileName());
|
||||
logger.info("({}/{}) Persisting package {}", count, totalPackages, pkgData.getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,28 +180,19 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||
|
||||
@SneakyThrows
|
||||
private void deletePackage(EntityManager em, String filename) {
|
||||
TypedQuery<PkgData> fquery = em.createQuery("SELECT p FROM PkgData p WHERE fileName = :fileName", PkgData.class);
|
||||
fquery.setParameter("fileName", filename);
|
||||
List<PkgData> savedFiles = fquery.getResultList();
|
||||
List<PkgData> savedFiles = Queries.getPackageByFileName(em, filename).getResultList();
|
||||
if (savedFiles.size() == 0) {
|
||||
throw JWO.newThrowable(IllegalArgumentException.class, "Package with name %s not found", filename);
|
||||
}
|
||||
PkgData pkg = fquery.getResultList().get(0);
|
||||
Files.delete(ctx.getFile(pkg));
|
||||
PkgData pkg = savedFiles.get(0);
|
||||
em.remove(pkg);
|
||||
Files.delete(ctx.getFile(pkg));
|
||||
}
|
||||
|
||||
static private final String deleteQuery =
|
||||
"SELECT p.fileName FROM PkgData p WHERE p.buildDate < :cutoff and p.id.name in \n" + "(SELECT p2.id.name FROM PkgData p2 GROUP BY p2.id.name HAVING count(p2.id.name) > :minVersions\n)";
|
||||
|
||||
private void deleteOld(EntityManager em) {
|
||||
TypedQuery<String> query = em.createQuery(deleteQuery, String.class);
|
||||
Calendar cutoff = Calendar.getInstance();
|
||||
cutoff.add(Calendar.YEAR, -2);
|
||||
query.setParameter("cutoff", OffsetDateTime.now());
|
||||
query.setParameter("minVersions", 2L);
|
||||
List<String> list = query.getResultList();
|
||||
list.forEach(this::deletePackage);
|
||||
Instant cutoff = Instant.now().minus(365 * 3, ChronoUnit.DAYS);
|
||||
Queries.getOldPackages2Delete(em, cutoff, 3L)
|
||||
.getResultStream()
|
||||
.forEach(this::deletePackage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,8 +204,101 @@ public class PacmanServiceEJB implements PacmanServiceLocal {
|
||||
|
||||
@Override
|
||||
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
|
||||
public List<PkgData> searchPackage(String name, String version, String arch, int pageNumber, int pageSize, String fileName) {
|
||||
public List<PkgData> searchPackage(String name,
|
||||
String version,
|
||||
String arch,
|
||||
CompressionFormat compressionFormat,
|
||||
String fileName,
|
||||
int pageNumber,
|
||||
int pageSize) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return QueryEngine.searchPackage(em, name, version, arch, pageNumber, pageSize, null);
|
||||
return Queries.searchPackage(em, name, version, arch, compressionFormat, fileName)
|
||||
.setMaxResults(pageSize)
|
||||
.setFirstResult(pageNumber * pageSize)
|
||||
.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> searchName(@Nonnull String name) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return Queries.searchPackageName(em, name).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PkgData> searchByFileName(@Nonnull String fileName) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return Queries.searchPackagesByFileName(em, fileName).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PkgData> searchByHash(@Nonnull String hash) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return Queries.searchPackagesByHash(em, hash).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listFiles() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return Queries.listFiles(em).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listHashes() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return Queries.listHashes(em).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
|
||||
public List<PkgId> searchPkgId(
|
||||
String name, String version, String arch, CompressionFormat compressionFormat) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return Queries.searchPackages(em, name, version, arch, compressionFormat).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
@Nullable
|
||||
public Long getFileSize(String fileName) {
|
||||
java.nio.file.Path res = ctx.getFile(fileName);
|
||||
if (!Files.exists(res)) return null;
|
||||
return Files.size(res);
|
||||
}
|
||||
|
||||
public Set<String> missingFiles(Collection<String> fileNames) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
Stream<String> result = fileNames.stream();
|
||||
Set<String> existing = Queries.getExistingFiles(em, fileNames)
|
||||
.getResultStream().collect(CollectionUtils.toUnmodifiableTreeSet());
|
||||
return result.filter(JWO.not(existing::contains))
|
||||
.collect(CollectionUtils.toUnmodifiableTreeSet());
|
||||
}
|
||||
|
||||
public NavigableMap<PkgId, PkgTuple> getPkgMap() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return Queries.getPkgMap(em).getResultStream().map(tuple -> {
|
||||
PkgId pkgId = tuple.get(0, PkgId.class);
|
||||
String filename = tuple.get(1, String.class);
|
||||
long size = tuple.get(2, Long.class);
|
||||
String md5sum = tuple.get(3, String.class);;
|
||||
PkgTuple pkgTuple = new PkgTuple();
|
||||
pkgTuple.setFileName(filename);
|
||||
pkgTuple.setSize(size);
|
||||
pkgTuple.setMd5sum(md5sum);
|
||||
return Tuple2.newInstance(pkgId, pkgTuple);
|
||||
}).collect(
|
||||
CollectionUtils.toUnmodifiableTreeMap(
|
||||
Tuple2<PkgId, PkgTuple>::get_1,
|
||||
Tuple2<PkgId, PkgTuple>::get_2,
|
||||
PkgIdComparator.getComparator()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PkgData getPackage(PkgId pkgId) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
return em.find(PkgData.class, pkgId);
|
||||
}
|
||||
}
|
@@ -2,7 +2,6 @@ package net.woggioni.jpacrepo.service;
|
||||
|
||||
import jakarta.ejb.ConcurrencyManagement;
|
||||
import jakarta.ejb.ConcurrencyManagementType;
|
||||
import jakarta.ejb.Singleton;
|
||||
import jakarta.ejb.TransactionAttribute;
|
||||
import jakarta.ejb.TransactionAttributeType;
|
||||
import jakarta.ejb.TransactionManagement;
|
||||
@@ -35,7 +34,6 @@ import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.StreamingOutput;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.val;
|
||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||
@@ -43,9 +41,9 @@ import net.woggioni.jpacrepo.api.service.PacmanServiceLocal;
|
||||
import net.woggioni.jpacrepo.config.AppConfig;
|
||||
import net.woggioni.jpacrepo.impl.model.CompressionFormatImpl;
|
||||
import net.woggioni.jpacrepo.impl.model.PkgDataImpl;
|
||||
import net.woggioni.jpacrepo.service.wire.PkgDataList;
|
||||
import net.woggioni.jpacrepo.service.wire.PkgTuple;
|
||||
import net.woggioni.jpacrepo.service.wire.StringList;
|
||||
import net.woggioni.jpacrepo.api.wire.PkgDataList;
|
||||
import net.woggioni.jpacrepo.api.wire.PkgTuple;
|
||||
import net.woggioni.jpacrepo.api.wire.StringList;
|
||||
import net.woggioni.jpacrepo.version.PkgIdComparator;
|
||||
import net.woggioni.jpacrepo.version.VersionComparator;
|
||||
import net.woggioni.jwo.CollectionUtils;
|
||||
@@ -56,7 +54,6 @@ import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
@@ -72,11 +69,9 @@ import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Singleton
|
||||
@Path("/pkg")
|
||||
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
|
||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||
@@ -107,36 +102,7 @@ public class PacmanWebService {
|
||||
synchronized(this) {
|
||||
result = cachedMap;
|
||||
if (result == null) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<Object[]> query = em.createQuery(
|
||||
"SELECT pkg.id.name, pkg.id.version, pkg.id.arch, pkg.id.compressionFormat, pkg.fileName, pkg.size, pkg.md5sum " +
|
||||
"FROM PkgData pkg ORDER BY pkg.id.name, pkg.id.version, pkg.id.arch",
|
||||
Object[].class);
|
||||
cachedMap = query.getResultStream()
|
||||
.map((Object[] pkg) -> {
|
||||
String name = (String) pkg[0];
|
||||
String version = (String) pkg[1];
|
||||
String arch = (String) pkg[2];
|
||||
CompressionFormat compressionFormat = (CompressionFormat) pkg[3];
|
||||
String filename = (String) pkg[4];
|
||||
long size = (long) pkg[5];
|
||||
String md5sum = (String) pkg[6];
|
||||
PkgTuple tuple = new PkgTuple();
|
||||
tuple.setFilename(filename);
|
||||
tuple.setSize(size);
|
||||
tuple.setMd5sum(md5sum);
|
||||
PkgId id = new PkgId();
|
||||
id.setName(name);
|
||||
id.setVersion(version);
|
||||
id.setArch(arch);
|
||||
id.setCompressionFormat(compressionFormat);
|
||||
return Tuple2.newInstance(id, tuple);
|
||||
}).collect(
|
||||
CollectionUtils.toUnmodifiableTreeMap(
|
||||
Tuple2<PkgId, PkgTuple>::get_1,
|
||||
Tuple2<PkgId, PkgTuple>::get_2,
|
||||
PkgIdComparator.getComparator())
|
||||
);
|
||||
cachedMap = service.getPkgMap();
|
||||
ctx.getInvalidateCache().set(false);
|
||||
result = cachedMap;
|
||||
}
|
||||
@@ -162,46 +128,26 @@ public class PacmanWebService {
|
||||
@GET
|
||||
@Path("searchByName/{name}")
|
||||
public Response searchByName(@PathParam("name") String name) {
|
||||
val em = emf.createEntityManager();
|
||||
if (name == null) throw new WebApplicationException(Response.Status.BAD_REQUEST);
|
||||
String query = String.format("SELECT pkgId.name FROM PkgId pkgId WHERE LOWER(pkgId.name) LIKE '%%%s%%' ORDER BY pkgId.name", name);
|
||||
return Response.ok(em.createQuery(query, String.class).getResultList()).build();
|
||||
return Response.ok(service.searchName(name)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("searchByHash/{md5sum}")
|
||||
public Response searchByHash(@PathParam("md5sum") String md5sum) {
|
||||
if (md5sum == null) throw new WebApplicationException(Response.Status.BAD_REQUEST);
|
||||
return getPackageByHash(md5sum);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("list/{name}")
|
||||
public Response getPackage(@PathParam("name") String name) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<String> query = em.createQuery("SELECT pkg.id.version FROM PkgData pkg WHERE pkg.id.name = :name ORDER BY pkg.id.version", String.class);
|
||||
query.setParameter("name", name);
|
||||
return Response.ok(new StringList(query.getResultList())).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("list/{name}/{version}")
|
||||
public Response getPackage(@PathParam("name") String name, @PathParam("version") String version) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<String> query = em.createQuery("SELECT pkg.arch FROM PkgData pkg WHERE pkg.id.name = :name AND pkg.id.version = :version ORDER BY pkg.id.arch", String.class);
|
||||
query.setParameter("name", name);
|
||||
query.setParameter("version", version);
|
||||
return Response.ok(new StringList(query.getResultList())).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("list/{name}/{version}/{arch}")
|
||||
public Response getPackage(@PathParam("name") String name, @PathParam("version") String version, @PathParam("arch") String arch) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<PkgData> query = em.createQuery("SELECT pkg FROM PkgData pkg WHERE " + "pkg.id.name = :name AND " + "pkg.id.version = :version AND " + "pkg.id.arch = :arch " + "ORDER BY pkg.arch", PkgData.class);
|
||||
query.setParameter("name", name);
|
||||
query.setParameter("version", version);
|
||||
query.setParameter("arch", arch);
|
||||
return Response.ok(query.getSingleResult()).build();
|
||||
@Path("id/search")
|
||||
public Response searchPackages(
|
||||
@QueryParam("name") String name,
|
||||
@QueryParam("version") String version,
|
||||
@QueryParam("arch") String arch,
|
||||
@QueryParam("compressionFormat") CompressionFormat compressionFormat
|
||||
) {
|
||||
return Response.ok(service.searchPkgId(name, version, arch, compressionFormat)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -213,7 +159,7 @@ public class PacmanWebService {
|
||||
cc.setMustRevalidate(true);
|
||||
cc.setNoCache(true);
|
||||
|
||||
NavigableMap<PkgId, PkgTuple> cachedMap = getCachedMap();
|
||||
NavigableMap<PkgId, PkgTuple> cachedMap = service.getPkgMap();
|
||||
EntityTag etag = new EntityTag(Integer.toString(cachedMap.hashCode()), false);
|
||||
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
||||
if (builder == null) {
|
||||
@@ -227,7 +173,7 @@ public class PacmanWebService {
|
||||
Collectors.mapping(
|
||||
Map.Entry::getValue,
|
||||
CollectionUtils.toUnmodifiableTreeSet(
|
||||
Comparator.comparing(PkgTuple::getFilename)
|
||||
Comparator.comparing(PkgTuple::getFileName)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -244,31 +190,27 @@ public class PacmanWebService {
|
||||
@GET
|
||||
@Path("hashes")
|
||||
public Response getHashes() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<String> query = em.createQuery("SELECT p.md5sum FROM PkgData p", String.class);
|
||||
return Response.ok(new StringList(query.getResultList())).build();
|
||||
return Response.ok(new StringList(service.listHashes())).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("files")
|
||||
public Response getFiles() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<String> query = em.createQuery("SELECT p.fileName FROM PkgData p", String.class);
|
||||
return Response.ok(new StringList(query.getResultList())).build();
|
||||
return Response.ok(new StringList(service.listFiles())).build();
|
||||
}
|
||||
|
||||
private Response getPackageByHash(String md5sum) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<PkgData> hquery = em.createNamedQuery("searchByHash", PkgData.class);
|
||||
if (md5sum != null) hquery.setParameter("md5sum", md5sum);
|
||||
return manageQueryResult(hquery.getResultList(), true);
|
||||
return manageQueryResult(service.searchByHash(md5sum), true);
|
||||
}
|
||||
|
||||
private Response getPackageByFileName(String file) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<PkgData> fnquery = em.createNamedQuery("searchByFileName", PkgData.class);
|
||||
fnquery.setParameter("fileName", file);
|
||||
return manageQueryResult(fnquery.getResultList(), true);
|
||||
@GET
|
||||
@Path("file/{fileName}")
|
||||
private Response getPackageByFileName(String fileName) {
|
||||
try {
|
||||
return Response.ok(service.searchByFileName(fileName)).build();
|
||||
} catch (NoResultException nre) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -282,9 +224,9 @@ public class PacmanWebService {
|
||||
EntityTag etag = new EntityTag(Integer.toString(getCachedMap().hashCode()));
|
||||
Response.ResponseBuilder builder = request.evaluatePreconditions(etag);
|
||||
if (builder == null) {
|
||||
java.nio.file.Path res = ctx.getFile(fileName);
|
||||
if (!Files.exists(res)) throw new NotFoundException(String.format("File '%s' was not found", fileName));
|
||||
builder = Response.ok(Files.size(res));
|
||||
Long size = service.getFileSize(fileName);
|
||||
if (size == null) throw new NotFoundException(String.format("File '%s' was not found", fileName));
|
||||
builder = Response.ok(size);
|
||||
builder.tag(etag);
|
||||
}
|
||||
builder.cacheControl(cc);
|
||||
@@ -296,37 +238,31 @@ public class PacmanWebService {
|
||||
@Path("download/{filename}")
|
||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||
public Response downloadPackage(@PathParam("filename") String fileName) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
TypedQuery<PkgData> fnquery = em.createNamedQuery("searchByFileName", PkgData.class);
|
||||
fnquery.setParameter("fileName", fileName);
|
||||
try {
|
||||
PkgData pkg = fnquery.getSingleResult();
|
||||
List<PkgData> pkgs = service.searchByFileName(fileName);
|
||||
if(pkgs.isEmpty()) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
} else if(pkgs.size() == 1) {
|
||||
PkgData pkg = pkgs.get(0);
|
||||
StreamingOutput stream = (OutputStream output) -> {
|
||||
try(InputStream is = Files.newInputStream(ctx.getFile(pkg))) {
|
||||
try (InputStream is = Files.newInputStream(ctx.getFile(pkg))) {
|
||||
JWO.copy(is, output, 0x10000);
|
||||
}
|
||||
};
|
||||
return Response.ok(stream).header("Content-Length", Files.size(ctx.getFile(pkg))).build();
|
||||
} catch(NoResultException nre) {
|
||||
throw new NotFoundException();
|
||||
} else {
|
||||
throw new RuntimeException("This should never happen");
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/doYouWantAny")
|
||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||
public Response doYouWantAny(List<String> filenames) {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
Set<String> result = filenames.stream().collect(CollectionUtils.toTreeSet());
|
||||
if (!result.isEmpty()) {
|
||||
TypedQuery<String> query = em.createQuery("SELECT pkg.fileName from PkgData pkg WHERE pkg.fileName in :filenames", String.class);
|
||||
query.setParameter("filenames", filenames);
|
||||
Set<String> toBeRemoved = query.getResultStream().collect(CollectionUtils.toTreeSet());
|
||||
result.removeAll(toBeRemoved);
|
||||
return Response.ok(new StringList(result)).build();
|
||||
public Response doYouWantAny(List<String> fileNames) {
|
||||
if (fileNames.isEmpty()) {
|
||||
return Response.ok(fileNames).build();
|
||||
}
|
||||
else {
|
||||
return Response.ok(result.toArray()).build();
|
||||
return Response.ok(new StringList(service.missingFiles(fileNames))).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,9 +278,7 @@ public class PacmanWebService {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
if (filename == null) throw new BadRequestException();
|
||||
java.nio.file.Path file = Files.createTempFile(ctx.getRepoFolder(), filename, null);
|
||||
TypedQuery<PkgData> fquery = em.createNamedQuery("searchByFileName", PkgData.class);
|
||||
fquery.setParameter("fileName", filename);
|
||||
List<PkgData> savedFiles = fquery.getResultList();
|
||||
List<PkgData> savedFiles = service.searchByFileName(filename);
|
||||
Response result;
|
||||
if (savedFiles.size() > 0) result = Response.notModified().build();
|
||||
else {
|
||||
@@ -374,14 +308,23 @@ public class PacmanWebService {
|
||||
|
||||
@GET
|
||||
@Path("/search")
|
||||
public List<PkgData> searchPackage(
|
||||
public PkgDataList searchPackage(
|
||||
@QueryParam("name") String name,
|
||||
@QueryParam("version") String version,
|
||||
@QueryParam("arch") String arch,
|
||||
@QueryParam("compressionFormat") CompressionFormat compressionFormat,
|
||||
@QueryParam("fileName") String fileName,
|
||||
@QueryParam("page") int pageNumber,
|
||||
@QueryParam("pageSize") int pageSize,
|
||||
@QueryParam("fileName") String fileName) {
|
||||
return service.searchPackage(name, version, arch, pageNumber, pageSize, fileName);
|
||||
@QueryParam("pageSize") int pageSize) {
|
||||
return new PkgDataList(service.searchPackage(
|
||||
name,
|
||||
version,
|
||||
arch,
|
||||
compressionFormat,
|
||||
fileName,
|
||||
pageNumber,
|
||||
Optional.of(pageSize).filter(it -> it > 0).orElse(10)
|
||||
));
|
||||
}
|
||||
|
||||
@OPTIONS
|
||||
|
281
src/main/java/net/woggioni/jpacrepo/service/jpa/Queries.java
Normal file
281
src/main/java/net/woggioni/jpacrepo/service/jpa/Queries.java
Normal file
@@ -0,0 +1,281 @@
|
||||
package net.woggioni.jpacrepo.service.jpa;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Tuple;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Path;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import jakarta.persistence.criteria.Subquery;
|
||||
import jakarta.persistence.metamodel.EntityType;
|
||||
import jakarta.persistence.metamodel.Metamodel;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.woggioni.jpacrepo.api.model.CompressionFormat;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData;
|
||||
import net.woggioni.jpacrepo.api.model.PkgData_;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId;
|
||||
import net.woggioni.jpacrepo.api.model.PkgId_;
|
||||
import net.woggioni.jwo.JWO;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Queries {
|
||||
private interface PredicateSupplier<T> {
|
||||
Predicate get(CriteriaBuilder cb, Root<T> root);
|
||||
}
|
||||
|
||||
public static TypedQuery<String> listAllPackageFiles(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
CriteriaQuery<String> criteriaQuery = cb.createQuery(String.class);
|
||||
Root<PkgData> root = criteriaQuery.from(metamodel.entity(PkgData.class));
|
||||
criteriaQuery.select(root.get(PkgData_.fileName));
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<PkgData> getPackageByFileName(EntityManager em, String fileName) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
CriteriaQuery<PkgData> criteriaQuery = cb.createQuery(PkgData.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
Predicate predicate = cb.equal(root.get(PkgData_.fileName), fileName);
|
||||
criteriaQuery.select(root).where(predicate);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<Instant> getUpdateTimestampByFileName(EntityManager em, String fileName) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
CriteriaQuery<Instant> criteriaQuery = cb.createQuery(Instant.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
Predicate predicate = cb.equal(root.get(PkgData_.fileName), fileName);
|
||||
criteriaQuery.select(root.get(PkgData_.updTimestamp)).where(predicate);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<String> getOldPackages2Delete(
|
||||
EntityManager em,
|
||||
Instant cutoff,
|
||||
long minNumberOfDifferentVersions) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<String> criteriaQuery = cb.createQuery(String.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> pkgDataRoot = criteriaQuery.from(entity);
|
||||
Subquery<String> subQuery = criteriaQuery.subquery(String.class);
|
||||
Root<PkgData> pkgDataRootSub = subQuery.from(entity);
|
||||
Path<PkgId> pkgIdPathSub = pkgDataRootSub.get(PkgData_.id);
|
||||
Predicate havingPredicate = cb.greaterThan(cb.count(
|
||||
pkgIdPathSub.get(PkgId_.version)), minNumberOfDifferentVersions);
|
||||
subQuery.select(pkgIdPathSub.get(PkgId_.name))
|
||||
.groupBy(
|
||||
pkgIdPathSub.get(PkgId_.name),
|
||||
pkgIdPathSub.get(PkgId_.arch)
|
||||
).having(havingPredicate);
|
||||
Predicate predicate = cb.and(
|
||||
cb.lessThan(pkgDataRoot.get(PkgData_.buildDate), cutoff),
|
||||
pkgDataRoot.get(PkgData_.id).get(PkgId_.name).in(subQuery.getSelection())
|
||||
);
|
||||
criteriaQuery.select(pkgDataRoot.get(PkgData_.fileName))
|
||||
.where(predicate)
|
||||
.orderBy(cb.asc(pkgDataRoot.get(PkgData_.fileName)));
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<Long> countPackagesByHash(EntityManager em, String hash) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> criteriaQuery = cb.createQuery(Long.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> pkgDataRoot = criteriaQuery.from(entity);
|
||||
Predicate predicate = cb.equal(pkgDataRoot.get(PkgData_.md5sum), hash);
|
||||
criteriaQuery.select(cb.count(pkgDataRoot)).where(predicate);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
private static <T> TypedQuery<PkgData> searchPackagesByPredicate(EntityManager em,
|
||||
PredicateSupplier<PkgData> predicateSupplier) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<PkgData> criteriaQuery = cb.createQuery(PkgData.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> pkgDataRoot = criteriaQuery.from(entity);
|
||||
criteriaQuery.select(pkgDataRoot).where(predicateSupplier.get(cb, pkgDataRoot));
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<PkgData> searchPackagesByHash(EntityManager em, String hash) {
|
||||
return searchPackagesByPredicate(em, (cb, root) -> cb.equal(root.get(PkgData_.md5sum), hash));
|
||||
}
|
||||
|
||||
public static TypedQuery<PkgData> searchPackagesByFileName(EntityManager em, String fileName) {
|
||||
return searchPackagesByPredicate(em, (cb, root) -> cb.equal(root.get(PkgData_.fileName), fileName));
|
||||
}
|
||||
|
||||
public static TypedQuery<Long> getSize(EntityManager em, String fileName) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> criteriaQuery = cb.createQuery(Long.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> pkgDataRoot = criteriaQuery.from(entity);
|
||||
Predicate predicate = cb.equal(pkgDataRoot.get(PkgData_.fileName), fileName);
|
||||
criteriaQuery.select(pkgDataRoot.get(PkgData_.size)).where(predicate);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<String> searchPackageName(EntityManager em, String needle) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<String> criteriaQuery = cb.createQuery(String.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
Path<PkgId> pkgIdPath = root.get(PkgData_.id);
|
||||
Predicate predicate = cb.like(
|
||||
cb.lower(pkgIdPath.get(PkgId_.name)),
|
||||
"%%" + needle + "%%"
|
||||
);
|
||||
criteriaQuery.select(pkgIdPath.get(PkgId_.name))
|
||||
.where(predicate)
|
||||
.orderBy(cb.asc(pkgIdPath.get(PkgId_.name)));
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<String> listFiles(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<String> criteriaQuery = cb.createQuery(String.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
criteriaQuery.select(root.get(PkgData_.fileName))
|
||||
.orderBy(cb.asc(root.get(PkgData_.fileName)));
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<String> listHashes(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<String> criteriaQuery = cb.createQuery(String.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
criteriaQuery.select(root.get(PkgData_.md5sum))
|
||||
.orderBy(cb.asc(root.get(PkgData_.md5sum)));
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<PkgId> searchPackages(EntityManager em,
|
||||
String name,
|
||||
String version,
|
||||
String arch,
|
||||
CompressionFormat compressionFormat) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<PkgId> criteriaQuery = cb.createQuery(PkgId.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
Path<PkgId> pkgIdRoot = root.get(PkgData_.id);
|
||||
Predicate[] predicates = JWO.streamCat(
|
||||
Optional.ofNullable(name)
|
||||
.map(it -> cb.equal(pkgIdRoot.get(PkgId_.name), it)).stream(),
|
||||
Optional.ofNullable(version)
|
||||
.map(it -> cb.equal(pkgIdRoot.get(PkgId_.version), it)).stream(),
|
||||
Optional.ofNullable(arch)
|
||||
.map(it -> cb.equal(pkgIdRoot.get(PkgId_.name), it)).stream(),
|
||||
Optional.ofNullable(compressionFormat)
|
||||
.map(it -> cb.equal(pkgIdRoot.get(PkgId_.compressionFormat), it)).stream()
|
||||
).toArray(Predicate[]::new);
|
||||
criteriaQuery.select(pkgIdRoot)
|
||||
.where(cb.and(predicates))
|
||||
.orderBy(
|
||||
cb.asc(pkgIdRoot.get(PkgId_.name)),
|
||||
cb.asc(pkgIdRoot.get(PkgId_.version)),
|
||||
cb.asc(pkgIdRoot.get(PkgId_.arch)),
|
||||
cb.asc(pkgIdRoot.get(PkgId_.compressionFormat))
|
||||
);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<String> getExistingFiles(EntityManager em, Collection<String> fileNames) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<String> criteriaQuery = cb.createQuery(String.class);
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
Predicate predicate = root.get(PkgData_.fileName).in(fileNames);
|
||||
criteriaQuery.select(root.get(PkgData_.fileName)).where(predicate);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<Tuple> getPkgMap(EntityManager em) {
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> criteriaQuery = cb.createTupleQuery();
|
||||
Metamodel metamodel = em.getMetamodel();
|
||||
EntityType<PkgData> entity = metamodel.entity(PkgData.class);
|
||||
Root<PkgData> root = criteriaQuery.from(entity);
|
||||
Path<PkgId> idPath = root.get(PkgData_.id);
|
||||
criteriaQuery.multiselect(
|
||||
idPath,
|
||||
root.get(PkgData_.fileName),
|
||||
root.get(PkgData_.size),
|
||||
root.get(PkgData_.md5sum)
|
||||
).orderBy(
|
||||
cb.asc(idPath.get(PkgId_.arch)),
|
||||
cb.asc(idPath.get(PkgId_.name)),
|
||||
cb.asc(idPath.get(PkgId_.version)),
|
||||
cb.asc(idPath.get(PkgId_.compressionFormat))
|
||||
);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
public static TypedQuery<PkgData> searchPackage(
|
||||
EntityManager em, String name,
|
||||
String version,
|
||||
String arch,
|
||||
CompressionFormat compressionFormat,
|
||||
String fileName) {
|
||||
CriteriaQuery<PkgData> criteriaQuery;
|
||||
CriteriaBuilder builder = em.getCriteriaBuilder();
|
||||
criteriaQuery = builder.createQuery(PkgData.class);
|
||||
Root<PkgData> entity = criteriaQuery.from(PkgData.class);
|
||||
Path<PkgId> pkgIdPath = entity.get(PkgData_.id);
|
||||
Predicate predicate = builder.and(JWO.streamCat(
|
||||
JWO.optional2Stream(
|
||||
Optional.ofNullable(name)
|
||||
.filter(JWO.not(String::isEmpty))
|
||||
.map(it -> builder.equal(pkgIdPath.get(PkgId_.name), it))),
|
||||
JWO.optional2Stream(
|
||||
Optional.ofNullable(version)
|
||||
.filter(JWO.not(String::isEmpty))
|
||||
.map(it -> builder.equal(pkgIdPath.get(PkgId_.version), it))),
|
||||
JWO.optional2Stream(
|
||||
Optional.ofNullable(arch)
|
||||
.filter(JWO.not(String::isEmpty))
|
||||
.map(it -> builder.equal(pkgIdPath.get(PkgId_.arch), it))),
|
||||
JWO.optional2Stream(
|
||||
Optional.ofNullable(compressionFormat)
|
||||
.map(it -> builder.equal(pkgIdPath.get(PkgId_.compressionFormat), it))),
|
||||
JWO.optional2Stream(
|
||||
Optional.ofNullable(fileName)
|
||||
.filter(JWO.not(String::isEmpty))
|
||||
.map(it -> builder.equal(entity.get(PkgData_.fileName), it)))
|
||||
).toArray(Predicate[]::new));
|
||||
criteriaQuery.select(entity)
|
||||
.where(predicate)
|
||||
.orderBy(
|
||||
builder.asc(pkgIdPath.get(PkgId_.name)),
|
||||
builder.asc(pkgIdPath.get(PkgId_.version)),
|
||||
builder.asc(pkgIdPath.get(PkgId_.arch)),
|
||||
builder.asc(pkgIdPath.get(PkgId_.compressionFormat)),
|
||||
builder.asc(entity.get(PkgData_.fileName))
|
||||
);
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package net.woggioni.jpacrepo.service.jpa;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import jakarta.persistence.criteria.Selection;
|
||||
import jakarta.persistence.metamodel.Metamodel;
|
||||
|
||||
public class QueryBuilder<T> {
|
||||
private final EntityManager em;
|
||||
private final CriteriaBuilder cb;
|
||||
private final CriteriaQuery<T> criteriaQuery;
|
||||
private final Metamodel metamodel;
|
||||
public QueryBuilder(EntityManager em, Class<T> cls) {
|
||||
this.em = em;
|
||||
this.cb = em.getCriteriaBuilder();
|
||||
this.criteriaQuery = cb.createQuery(cls);
|
||||
this.metamodel = em.getMetamodel();
|
||||
}
|
||||
|
||||
public QueryBuilder<T> select(Selection<? extends T> a) {
|
||||
criteriaQuery.select(a);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <U> Root<U> from(Class<U> cls) {
|
||||
return criteriaQuery.from(metamodel.entity(cls));
|
||||
}
|
||||
|
||||
public TypedQuery<T> build() {
|
||||
return em.createQuery(criteriaQuery);
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
|
||||
version="4.0" bean-discovery-mode="annotated">
|
||||
</beans>
|
@@ -11,14 +11,14 @@
|
||||
|
||||
<properties>
|
||||
<property name="org.jboss.logging.provider" value="log4j2"/>
|
||||
<property name="javax.persistence.schema-generation.create-source" value="script-then-metadata"/>
|
||||
<property name="javax.persistence.schema-generation.create-script-source"
|
||||
<property name="jakarta.persistence.schema-generation.create-source" value="script-then-metadata"/>
|
||||
<property name="jakarta.persistence.schema-generation.create-script-source"
|
||||
value="META-INF/sql/CreateSchema.sql"/>
|
||||
<property name="javax.persistence.schema-generation.drop-source" value="metadata-then-script"/>
|
||||
<property name="javax.persistence.schema-generation.drop-script-source"
|
||||
<property name="jakarta.persistence.schema-generation.drop-source" value="metadata-then-script"/>
|
||||
<property name="jakarta.persistence.schema-generation.drop-script-source"
|
||||
value="META-INF/sql/DropSchema.sql"/>
|
||||
<property name="hibernate.default_schema" value="jpacrepo"/>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect"/>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
<error-page>
|
||||
<error-code>404</error-code>
|
||||
<location>404.xhtml</location>
|
||||
<location>/404.xhtml</location>
|
||||
</error-page>
|
||||
|
||||
</web-app>
|
||||
|
@@ -116,6 +116,7 @@ public class ClientTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeStatelessBean() throws Exception {
|
||||
Properties prop = new Properties();
|
||||
InputStream in = getClass().getClassLoader().getResourceAsStream("jboss-ejb-client.properties");
|
||||
@@ -123,13 +124,13 @@ public class ClientTest {
|
||||
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
|
||||
|
||||
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
|
||||
prop.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
|
||||
// prop.put(Context.PROVIDER_URL, "http-remoting://nuc:8080");
|
||||
prop.put(Context.PROVIDER_URL, "http-remoting://localhost:7080");
|
||||
// prop.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
|
||||
// prop.put(Context.PROVIDER_URL, "remote://odroid-u3:4447");
|
||||
// prop.put(Context.SECURITY_PRINCIPAL, "walter");
|
||||
// prop.put(Context.SECURITY_CREDENTIALS, "27ff5990757d1d");
|
||||
prop.put(Context.SECURITY_PRINCIPAL, "luser");
|
||||
prop.put(Context.SECURITY_CREDENTIALS, "123456");
|
||||
prop.put(Context.SECURITY_PRINCIPAL, "walter");
|
||||
prop.put(Context.SECURITY_CREDENTIALS, "27ff5990757d1d");
|
||||
// prop.put(Context.SECURITY_PRINCIPAL, "luser");
|
||||
// prop.put(Context.SECURITY_CREDENTIALS, "123456");
|
||||
|
||||
prop.put("jboss.naming.client.ejb.context", true);
|
||||
Context context = new InitialContext(prop);
|
||||
@@ -137,11 +138,21 @@ public class ClientTest {
|
||||
traverseJndiNode("/", context);
|
||||
// final PacmanService stateService = (PacmanService) ctx.lookup("/jpacrepo-1.0/remote/PacmanServiceEJB!service.PacmanService");
|
||||
final PacmanServiceRemote service = (PacmanServiceRemote) ctx.lookup(
|
||||
"/jpacrepo-2.0-SNAPSHOT/PacmanServiceEJB!net.woggioni.jpacrepo.service.PacmanServiceRemote"
|
||||
"/jpacrepo-2023.07/PacmanServiceEJB!net.woggioni.jpacrepo.api.service.PacmanServiceRemote"
|
||||
);
|
||||
// List<PkgData> pkgs = service.searchPackage("google-earth", null, null, 1, 10);
|
||||
// System.out.println(new XStream().toXML(pkgs));
|
||||
service.syncDB();
|
||||
// service.searchPkgId("jre8-openjdk", null, null, null)
|
||||
// .stream()
|
||||
// .map(service::getPackage)
|
||||
// .filter(Objects::nonNull)
|
||||
// .map(PkgData::getFileName)
|
||||
// .forEach(System.out::println);
|
||||
// final TestEJB service = (TestEJB) ctx.lookup(
|
||||
// "/jpacrepo-2023.07TestEJBImpl!net.woggioni.jpacrepo.api.service.TestEJB"
|
||||
// );
|
||||
// System.out.println(service.hello());
|
||||
}
|
||||
|
||||
}
|
34
src/test/java/EJBTest.java
Normal file
34
src/test/java/EJBTest.java
Normal file
@@ -0,0 +1,34 @@
|
||||
import jakarta.ejb.embeddable.EJBContainer;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
import javax.naming.Context;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
public class EJBTest {
|
||||
|
||||
private EJBContainer ejbContainer = null;
|
||||
|
||||
private Context context = null;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
Arrays.stream(System.getProperty("java.class.path").split(System.getProperty("path.separator")))
|
||||
.filter(it -> it.toLowerCase(Locale.ROOT).endsWith(".war"))
|
||||
.forEach(System.out::println);
|
||||
Properties properties = new Properties();
|
||||
File[] files = Arrays.stream(System.getProperty("jpacrepo.jar.path").split(System.getProperty("path.separator")))
|
||||
.map(Path::of)
|
||||
.filter(Files::exists)
|
||||
.map(Path::toFile)
|
||||
.toArray(File[]::new);
|
||||
properties.put(EJBContainer.MODULES, files);
|
||||
ejbContainer = EJBContainer.createEJBContainer(properties);
|
||||
context = ejbContainer.getContext();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user